提示:本文由 AI 生成,用于学习和参考 Vue 指令的使用方法。
在 Vue 开发中,v-if
和 v-for
是两个最常用的指令。虽然经常一起使用,但优先级和性能问题容易被忽略。本文通过示例、源码分析和最佳实践,讲清楚两者的关系,并对 Vue2 与 Vue3 进行对比。
一、v-if 与 v-for 的作用
v-if
- 条件渲染指令,只有表达式为
true
时,节点才会渲染。 - 不满足条件时,节点完全销毁。
ini
<Modal v-if="isShow" />
v-for
- 列表渲染指令,基于数组或对象生成一组元素。
- 语法:
item in items
,建议为每个节点设置唯一key
,便于 diff 算法优化。
css
<li v-for="item in items" :key="item.id">
{{ item.label }}
</li>
二、执行顺序与优先级
1. v-if 与 v-for 在同一元素上
ini
<p v-for="item in items" v-if="item.show">{{ item.title }}</p>
执行流程:
-
v-for 先执行
- 根据
items
数组生成循环模板,每个item
都生成一个待渲染的虚拟节点(VNode)。
- 根据
-
v-if 在每个节点上执行
- 判断
item.show
是否为true
,决定是否渲染节点。
- 判断
等效伪代码:
ini
items.forEach(item => {
if (item.show) {
render(<p>{item.title}</p>);
}
});
结论:同一元素上,v-for 优先,v-if 后置。
问题:
- 性能浪费:大数组时,虚拟 DOM 仍会生成所有节点。
- 可读性差:条件逻辑与循环混在一起。
2. v-if 放在最外层 template
ini
<template v-if="hasItems">
<p v-for="item in items" :key="item.id">{{ item.title }}</p>
</template>
- 先判断条件
hasItems
,再循环列表。 - 避免无效循环,性能更好。
三、Vue2 / Vue3 对比
特性 | Vue2 | Vue3 |
---|---|---|
优先级规则 | v-for 高于 v-if | 保持一致,v-for 高于 v-if |
编译产物 | _l 、_c |
renderList 、createVNode |
性能优化 | template v-if 或 computed | 同样推荐,可结合 v-memo |
四、最佳实践
-
不要在同一元素上同时使用 v-if 和 v-for
- 会先生成所有循环节点,再逐项判断条件,浪费性能。
-
外层 template 控制条件
xml
<template v-if="isShow">
<ul>
<li v-for="item in items" :key="item.id">{{ item.title }}</li>
</ul>
</template>
- 使用 computed 过滤列表
javascript
computed: {
visibleItems() {
return this.items.filter(item => item.show);
}
}
css
<p v-for="item in visibleItems" :key="item.id">{{ item.title }}</p>
- 条件判断提前,渲染函数只处理需要渲染的项,性能更高。
-
保证 key 唯一性
- 对列表渲染性能影响大,尤其是动态增删节点时。
五、总结
- 执行顺序:同一元素上,v-for 先生成循环节点 → v-if 判断。
- 最佳实践:将 v-if 放最外层 template 或用 computed 过滤,避免在循环内重复判断。
- Vue2 / Vue3 行为一致,只是渲染函数 API 不同。
- 一句话总结:**v-for 优先,v-if 后置;同用不佳,分开更快。