一个简单的
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>
在 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>
只需使用
v-if
即可。但首先,不要使用 track-by="id"
,因为有 null
项和 null
子项。您可以在此处查看演示https://jsfiddle.net/13mtm5zo/1/。
也许更好的方法是在渲染之前先处理数据。
我建议您不要在同一元素中使用 v-if 和 v-for。我发现有效且不影响性能的是:
<li v-for="(value, key) in row.item.filter(x => x !== null)" :key="key"{{value}}</li>
您只需对正在遍历的数组运行过滤函数即可。这是 C# 中的常见用法,发现在 JavaScript 中也没有什么不同。这基本上会在迭代时跳过空值。
希望这会有所帮助(3年后)。
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
首先,让我们从一般准则开始,因为其他答案中已经建议了:永远不要在同一元素上使用
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
渲染父列表和子列表中的项目选择是否使用
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
和
v-for
与 <template>
来渲染列表是一种很好的方法,可以让您最大限度地控制渲染的内容,同时还有助于避免在同一元素上使用这两个指令的陷阱。