在Vue2中
v-for
优先级比v-if
高,所以在同一个标签上同时使用v-if
和v-for
时,无论符不符合v-if
的条件v-for
都会遍历整个列表,这意味着 Vue 会先执行循环,再对每个元素应用条件判断。即使最终只有少量元素需要渲染,也会遍历整个列表,导致不必要的性能开销。
在Vue3中
v-if
比v-for
优先级高,相对于Vue2做了一些优化,Vue 会先进行条件判断,再决定是否执行循环。这减少了不必要的循环和 DOM 操作,提升了性能。但是如果v-if
的条件依赖于v-for
的每一项(例如v-if="item.isActive"
),Vue 仍然需要对整个列表进行遍历和条件判断。如果列表很大,这可能会导致性能问题。通过计算属性预先过滤列表,可以避免重复的条件判断,从而提升性能。
正确的解决方式
关键原则:让模板专注于展示渲染,数据逻辑通过计算属性
或方法
处理。
- 使用计算属性:在模板外进行过滤。
<template>
<div v-for="item in activeItems" :key="item.id">
{{ item.name }}
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Item 1', isActive: true },
{ id: 2, name: 'Item 2', isActive: false },
{ id: 3, name: 'Item 3', isActive: true }
]
};
},
computed: {
// 预先过滤出需要渲染的项
activeItems() {
return this.items.filter(item => item.isActive);
}
}
};
</script>
- 嵌套使用:将
v-if
放在外层元素上。
如果v-if
的条件不依赖于v-for
的每一项,可以将v-if
放在外层元素上。
<div v-if="shouldShow">
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</div>
- 使用
<template>
标签分离逻辑。
<template v-for="item in list">
<div v-if="item.isActive">{{ item.name }}</div>
</template>