在 Vue v-for 中跳过空项目和空子项目

问题描述 投票:0回答:6
vue.js null html-lists v-for
6个回答
33
投票

一个简单的

v-if
可能会起作用:

<li v-for="item in items" v-if="item !== null" track-by="id">

尝试一下。如果没有,请执行以下操作:

您可以为此添加一个过滤器(在应用程序实例之前的

main.js
中):

Vue.filter('removeNullProps', function(object) {
  return _.reject(object, (value) => value === null)
})

然后在模板中:

<li v-for="item in items | removeNullProps" track-by="id">
    <ol>
        <li v-for="child in item.children | removeNullProps" track-by="id"></li>
    </ol>
</li>

17
投票

在 Vue 2 中,过滤器已在

v-for
中被弃用。

现在您应该使用计算属性。下面是演示。

new Vue({
  el: '#app',
  data: {
    items: [
      'item 1',
      'item 2',
      null,
      'item 4',
      null,
      'item 6'
    ]
  },
  computed: {
    nonNullItems: function() {
      return this.items.filter(function(item) {
        return item !== null;
      });
    }
  }
})
<script src="https://unpkg.com/vue@2"></script>
<div id="app">
  Using a computed property:
  <ul>
    <li v-for="item in nonNullItems">
      {{ item }}
    </li>
  </ul>
  <hr>
  Using v-if:
  <ul>
    <li v-for="item in items" v-if="item !== null">
      {{ item }}
    </li>
  </ul>
</div>


4
投票

只需使用

v-if
即可。但首先,不要使用
track-by="id"
,因为有
null
项和
null
子项。您可以在此处查看演示https://jsfiddle.net/13mtm5zo/1/

也许更好的方法是在渲染之前先处理数据。


4
投票

我建议您不要在同一元素中使用 v-if 和 v-for。我发现有效且不影响性能的是:

<li v-for="(value, key) in row.item.filter(x => x !== null)" :key="key"{{value}}</li>

您只需对正在遍历的数组运行过滤函数即可。这是 C# 中的常见用法,发现在 JavaScript 中也没有什么不同。这基本上会在迭代时跳过空值。

希望这会有所帮助(3年后)。


0
投票

Vue.Js 风格指南告诉我们:

“切勿在与 v-for 相同的元素上使用 v-if。”

如何根据Vue风格指南正确处理v-if和v-for:

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

在此处查看有关如何使用

v-if
处理
v-for
的更多信息:https://v2.vuejs.org/v2/style-guide/#Avoid-v-if-with-v-for-essential


0
投票

首先,让我们从一般准则开始,因为其他答案中已经建议了:永远不要在同一元素上使用

v-if
v-for

由于这两个指令都控制是否渲染元素,因此将它们一起使用会令人困惑且容易出错。 在 Vue 2 中,

v-for
优先于
v-if
,但 在 Vue 3 中,反之亦然始终避免将它们一起使用

对于您的问题,如果您有一个列表列表,您实际上希望处理两种空值:空列表和这些列表中的空项。 我们可以通过将多个

v-if

v-for
编织在一起来处理这两个问题,两个列表各一对,第三个
v-if
以避免渲染空子列表:
<ul>
  <template v-for="item in Object.values(items)">
    <li v-if="item != null" :key="item.id">
      {{ `Parent #${item.id}: ${item.title}` }}
      <ol v-if="item.children != null && Object.values(item.children).length > 0">
        <template v-for="child in Object.values(item.children)">
          <li v-if="child != null" :key="child.id">
            {{ `Child #${child.id}: ${child.subtitle}` }}
          </li>
        </template>
      </ol>
    </li>
  </template>
</ul>

乍一看这可能有点复杂,但核心是:我们可以解决这个问题,同时避免 
v-if

v-for
限制,并使用
<template> 元素
 作为包装器。
通过在父列表和子列表中使用

<template>

作为列表项的包装,我们可以:


使用
    v-for
  1.  渲染父列表和子列表中的项目
    
    选择是否使用
  2. v-if
  3. 单独渲染每个项目,而不沿途创建一堆空的
    <li>
    
    
  4. 可运行代码片段示例:

new Vue({ el: '#app', data() { return { items: { 1: { id: 1, title: "This should be rendered", children: { 100: { id: 100, subtitle: "I am a child" }, 101: null, 102: { id: 102, subtitle: "I am a second child" }, } }, 2: null, // No parent #2 to render 3: { id: 3, title: "Should be rendered as well", children: { 300: { id: 300, subtitle: "I am a child under a different parent" }, } }, 4: { id: 4, title: "Should also be rendered (without children)", children: null }, } } }, });
<script src="https://unpkg.com/vue@2/dist/vue.min.js"></script>

<div id="app">
  <ul>
    <template v-for="item in Object.values(items)">
      <li v-if="item != null" :key="item.id">
        {{ `Parent ${item.id}: ${item.title}` }}
        <ol v-if="item.children != null && Object.values(item.children).length > 0">
          <template v-for="child in Object.values(item.children)">
            <li v-if="child != null" :key="child.id">
              {{ `Child ${child.id}: ${child.subtitle}` }}
            </li>
          </template>
        </ol>
      </li>
    </template>
  </ul>
</div>

使用分层

v-if

v-for
<template>
来渲染列表是一种很好的方法,可以让您最大限度地控制渲染的内容,同时还有助于避免在同一元素上使用这两个指令的陷阱。
    

© www.soinside.com 2019 - 2024. All rights reserved.