在Vue v-for中跳过null项和null子项

mlmc2os5  于 2023-04-07  发布在  Vue.js
关注(0)|答案(6)|浏览(225)

我在Vue.js中有一个嵌套的for ... in循环。我试图做的是,如果元素的值是null,则跳过元素。下面是Vue模板代码:

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

null元素可以同时存在于itemitem.children对象中。
例如:

var data = {
   1: {
      id: 1,
      title: "This should be rendered",
      children: {
          100: {
              id: 100,
              subtitle: "I am a child"
          },
          101: null
      }
   },
   2: null,
   3: {
       id: 3,
       title: "Should should be rendered as well",
       children: {}
   }
};

有了这个数据,data[1].children[101]不应该被渲染,如果data[1].children[100]后来变成null,它应该从列表中省略。
我无法控制这些数据的结构,所以我必须以这种形式处理它。

9njqaruj

9njqaruj1#

一个简单的v-if可以工作:

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

给予一下。如果没有,请这样做:
您可以为此添加一个过滤器(在App示例之前的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>
hvvq6cgz

hvvq6cgz2#

在Vue 2中,v-for s中的过滤器已被弃用。
现在你应该使用计算属性了。

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>
ws51t4hk

ws51t4hk3#

我建议你不要在同一个元素中使用v-if和v-for。我发现工作并且不影响性能的是:

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

你只需要在你要遍历的数组上运行filter函数。这是c#中的一个常见用法,发现在JavaScript中也没有什么不同。这基本上会在迭代时跳过null。
希望这对你有帮助(3年后)。

aelbi1ox

aelbi1ox4#

只需使用v-if来处理它。但首先,不要使用track-by="id",因为null项和null子项。您可以在这里查看https://jsfiddle.net/13mtm5zo/1/的演示。

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

dxpyg8gm5#

Vue.js风格指南告诉我们:
“永远不要在同一个元素上使用v-if和v-for。”
如何根据Vue样式指南正确处理v-if和v-for:

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

更多关于如何使用v-for处理v-if的信息,请参见:https://v2.vuejs.org/v2/style-guide/#Avoid-v-if-with-v-for-essential

wwtsj6pe

wwtsj6pe6#

首先,让我们从一个一般性的指导方针开始,因为它已经在其他答案中提出:永远不要在同一个元素上使用v-ifv-for
由于这两个指令都控制元素是否被渲染,所以一起使用它们会引起混淆并容易出错。在Vue 2中,v-for优先于v-if,但在Vue 3中,反之亦然-总是避免一起使用它们
对于你的问题,你有一个列表的列表,你实际上是在处理两种null值:空列表和这些列表中的空项。
我们可以通过像这样将多个v-ifv-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-ifv-for限制,使用<template> elements作为 Package 器。
通过使用<template> s作为列表项的 Package 器,在父列表和子列表中,我们都可以:
1.使用v-for渲染父列表和子列表中的项
1.选择是否使用v-if单独呈现每个项目,而不创建一堆空的<li>
可运行代码段示例:

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 s和v-for s以及<template〉s来呈现列表是一种很好的方法,可以给予您最大限度地控制要呈现的内容,同时还有助于避免在同一个元素上使用两个指令的陷阱。

相关问题