今天我们来聊聊 Vue 里两位“重量级”选手——v-if 和 v-for。
你是不是也曾在同一个标签上同时写过这两个指令?🤔 结果发现页面渲染出来的效果跟你预想的不太一样?或者在 Vue 2 和 Vue 3 之间反复横跳,被优先级搞晕了头?
别慌!这篇笔记不仅带你搞定基础用法,还要深扒它们的优先级战争和性能内幕,让你彻底吃透这两个指令!🔥
🛡️ v-if:条件渲染的“守门员”
v-if 的作用很简单:根据表达式的真假,来决定元素是“存在”还是“消失”。
- 真正的条件渲染:当条件为 false 时,元素压根不会出现在 DOM 树里,就像从来没写过一样。
- 生命周期:因为元素被销毁了,所以相关的组件生命周期钩子(如 mounted)也会随之触发。
常用搭档
- v-else-if:相当于 else if。
- v-else:相当于 else。
<div v-if="type === 'A'">
我是 A 类型
</div>
<div v-else-if="type === 'B'">
我是 B 类型
</div>
<div v-else>
我是默认类型
</div>
💡 性能小贴士
v-if 是惰性的。如果初始条件是 false,Vue 啥都不干。只有当条件第一次变成 true 时,它才开始渲染。所以,它适合那些不经常变化的条件。
👁️ v-show:CSS 的“障眼法”
虽然你问的是 v-if,但不得不提它的“双胞胎兄弟” v-show。
- 区别:v-show 不管条件真假,元素永远都在 DOM 里。它只是简单地切换 CSS 的 display 属性(none 或 block)。
- 场景:如果你需要非常频繁地切换显示状态(比如侧边栏折叠、Tab 切换),用 v-show 性能更好,因为它不需要反复销毁和重建 DOM。
🔄 v-for:列表渲染的“复印机”
v-for 用来循环渲染列表。它不仅能遍历数组,还能遍历对象、Map,甚至是一个数字(用来循环次数)。
基本语法
<!-- 遍历数组 -->
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.name }}
</li>
<!-- 遍历对象 -->
<div v-for="(value, key, index) in myObject">
{{ key }}: {{ value }}
</div>
⚠️ 核心铁律:必须加 :key!
千万别偷懒!:key 是 Vue 识别节点身份的“身份证”。
- 作用:帮助 Vue 的 Diff 算法高效地更新 DOM。
- 避坑:尽量不要用 index 作为 key(除非列表是静态的且没有输入框),最好用数据里唯一的 id。否则在列表排序或删除时,可能会出现渲染错误或性能问题。
⚔️ 巅峰对决:v-if 与 v-for 的优先级战争
这是面试高频考点,也是新手最容易踩的坑!当它们俩出现在同一个标签上时,谁听谁的?
答案取决于你的 Vue 版本!
Vue 2 时代:v-for 是老大
在 Vue 2 中,v-for 的优先级高于 v-if。这意味着:Vue 会先循环生成所有的列表项,然后再判断每一项是否符合 v-if 的条件。
- 后果:即使你只想显示几个符合条件的项,Vue 也会把整个列表遍历一遍,造成不必要的性能浪费。
Vue 3 时代:v-if 翻身做主人
在 Vue 3 中,v-if 的优先级高于 v-for。这意味着:Vue 会先判断条件。如果条件不满足,它压根就不会去执行循环。
- 后果:虽然性能优化了,但逻辑可能变得很奇怪——你可能想过滤列表,结果因为 v-if 先执行,导致你访问不到循环里的变量(比如 item.isActive),直接报错!
❌ 官方强烈建议:不要把它们写在同一个标签上!
✅ 最佳实践(无论 Vue 2 还是 3)
方法一:用计算属性(Computed)过滤
这是最优雅、性能最好的写法。
<!-- 模板里只负责展示 -->
<ul>
<li v-for="user in activeUsers" :key="user.id">
{{ user.name }}
</li>
</ul>
<!-- 逻辑里负责过滤 -->
<script setup>
import { computed } from 'vue';
const users = ref([...]); // 原始数据
// 计算属性自动过滤出活跃用户
const activeUsers = computed(() => {
return users.value.filter(user => user.isActive);
});
</script>
方法二:用 标签包裹
如果你不想用计算属性,可以用一个不可见的 标签来承载 v-for。
<template v-for="user in users" :key="user.id">
<li v-if="user.isActive">
{{ user.name }}
</li>
</template>
📌 总结一下
| 特性 | v-if | v-show | v-for |
|---|---|---|---|
| 手段 | 动态添加/移除 DOM | 切换 CSS display | 循环生成 DOM |
| 性能 | 初始渲染开销小 | 初始渲染开销大 | 需配合 :key |
| 场景 | 条件不常变 | 频繁切换显示 | 列表渲染 |
| 优先级 | Vue3 高 / Vue2 低 | - | Vue2 高 / Vue3 低 |
一句话口诀
“列表过滤用计算,频繁切换用 show,条件渲染用 if,key 值千万别忘!”
好啦,今天的 Vue 指令大揭秘就到这里!是不是感觉思路清晰多了?赶紧去检查一下你的代码,把那些混用的 v-if 和 v-for 改过来吧!