今天我们来聊聊 Vue 里两位“重量级”选手——v-if和v-for。你是不是也曾在同一个标签上同时写过这两个指令 结果发现页面渲染出来的效果跟你预想的不太一样或者在 Vue 2 和 Vue 3 之间反复横跳被优先级搞晕了头别慌这篇笔记不仅带你搞定基础用法还要深扒它们的优先级战争和性能内幕让你彻底吃透这两个指令️ v-if条件渲染的“守门员”v-if 的作用很简单根据表达式的真假来决定元素是**“存在”还是“消失”**。真正的条件渲染当条件为 false 时元素压根不会出现在 DOM 树里就像从来没写过一样。生命周期因为元素被销毁了所以相关的组件生命周期钩子如 mounted也会随之触发。常用搭档v-else-if相当于 else if。v-else相当于 else。divv-iftype A我是 A 类型/divdivv-else-iftype B我是 B 类型/divdivv-else我是默认类型/div 性能小贴士v-if 是惰性的。如果初始条件是 falseVue 啥都不干。只有当条件第一次变成 true 时它才开始渲染。所以它适合那些不经常变化的条件。️ v-showCSS 的“障眼法”虽然你问的是 v-if但不得不提它的“双胞胎兄弟”v-show。区别v-show 不管条件真假元素永远都在 DOM 里。它只是简单地切换 CSS 的 display 属性none 或 block。场景如果你需要非常频繁地切换显示状态比如侧边栏折叠、Tab 切换用 v-show 性能更好因为它不需要反复销毁和重建 DOM。 v-for列表渲染的“复印机”v-for 用来循环渲染列表。它不仅能遍历数组还能遍历对象、Map甚至是一个数字用来循环次数。基本语法!-- 遍历数组 --liv-for(item, index) in items:keyitem.id{{ index }} - {{ item.name }}/li!-- 遍历对象 --divv-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过滤这是最优雅、性能最好的写法。!-- 模板里只负责展示 --ulliv-foruser in activeUsers:keyuser.id{{ user.name }}/li/ul!-- 逻辑里负责过滤 --scriptsetupimport{computed}fromvue;constusersref([...]);// 原始数据// 计算属性自动过滤出活跃用户constactiveUserscomputed((){returnusers.value.filter(useruser.isActive);});/script方法二用 标签包裹如果你不想用计算属性可以用一个不可见的 标签来承载 v-for。templatev-foruser in users:keyuser.idliv-ifuser.isActive{{ user.name }}/li/template 总结一下特性v-ifv-showv-for手段动态添加/移除 DOM切换 CSS display循环生成 DOM性能初始渲染开销小初始渲染开销大需配合 :key场景条件不常变频繁切换显示列表渲染优先级Vue3 高 / Vue2 低-Vue2 高 / Vue3 低一句话口诀“列表过滤用计算频繁切换用 show条件渲染用 ifkey 值千万别忘”好啦今天的 Vue 指令大揭秘就到这里是不是感觉思路清晰多了赶紧去检查一下你的代码把那些混用的 v-if 和 v-for 改过来吧