Vue指令对决:v-if vs v-for|谁才是真正的“渲染之王”?

今天我们来聊聊 Vue 里两位“重量级”选手——v-ifv-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 改过来吧!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容