Vue指令對決:v-if vs v-for|誰才是真正的“渲染之王”?

今天我們來聊聊 Vue 里兩位“重量級”選手——v-ifv-for。

你是不是也曾在同一個(gè)標(biāo)簽上同時(shí)寫過這兩個(gè)指令??? 結(jié)果發(fā)現(xiàn)頁面渲染出來的效果跟你預(yù)想的不太一樣?或者在 Vue 2 和 Vue 3 之間反復(fù)橫跳,被優(yōu)先級搞暈了頭?

別慌!這篇筆記不僅帶你搞定基礎(chǔ)用法,還要深扒它們的優(yōu)先級戰(zhàn)爭性能內(nèi)幕,讓你徹底吃透這兩個(gè)指令!??


??? v-if:條件渲染的“守門員”

v-if 的作用很簡單:根據(jù)表達(dá)式的真假,來決定元素是“存在”還是“消失”。

  • 真正的條件渲染:當(dāng)條件為 false 時(shí),元素壓根不會(huì)出現(xiàn)在 DOM 樹里,就像從來沒寫過一樣。
  • 生命周期:因?yàn)樵乇讳N毀了,所以相關(guān)的組件生命周期鉤子(如 mounted)也會(huì)隨之觸發(fā)。

常用搭檔

  • v-else-if:相當(dāng)于 else if。
  • v-else:相當(dāng)于 else。
<div v-if="type === 'A'">
  我是 A 類型
</div>
<div v-else-if="type === 'B'">
  我是 B 類型
</div>
<div v-else>
  我是默認(rèn)類型
</div>

?? 性能小貼士

v-if 是惰性的。如果初始條件是 false,Vue 啥都不干。只有當(dāng)條件第一次變成 true 時(shí),它才開始渲染。所以,它適合那些不經(jīng)常變化的條件。


??? v-show:CSS 的“障眼法”

雖然你問的是 v-if,但不得不提它的“雙胞胎兄弟” v-show

  • 區(qū)別:v-show 不管條件真假,元素永遠(yuǎn)都在 DOM 里。它只是簡單地切換 CSS 的 display 屬性(none 或 block)。
  • 場景:如果你需要非常頻繁地切換顯示狀態(tài)(比如側(cè)邊欄折疊、Tab 切換),用 v-show 性能更好,因?yàn)樗恍枰磸?fù)銷毀和重建 DOM。

?? v-for:列表渲染的“復(fù)印機(jī)”

v-for 用來循環(huán)渲染列表。它不僅能遍歷數(shù)組,還能遍歷對象、Map,甚至是一個(gè)數(shù)字(用來循環(huán)次數(shù))。

基本語法

<!-- 遍歷數(shù)組 -->
<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 識別節(jié)點(diǎn)身份的“身份證”。

  • 作用:幫助 Vue 的 Diff 算法高效地更新 DOM。
  • 避坑:盡量不要用 index 作為 key(除非列表是靜態(tài)的且沒有輸入框),最好用數(shù)據(jù)里唯一的 id。否則在列表排序或刪除時(shí),可能會(huì)出現(xiàn)渲染錯(cuò)誤或性能問題。

?? 巔峰對決:v-if 與 v-for 的優(yōu)先級戰(zhàn)爭

這是面試高頻考點(diǎn),也是新手最容易踩的坑!當(dāng)它們倆出現(xiàn)在同一個(gè)標(biāo)簽上時(shí),誰聽誰的?

答案取決于你的 Vue 版本!

Vue 2 時(shí)代:v-for 是老大

在 Vue 2 中,v-for 的優(yōu)先級高于 v-if。這意味著:Vue 會(huì)先循環(huán)生成所有的列表項(xiàng),然后再判斷每一項(xiàng)是否符合 v-if 的條件。

  • 后果:即使你只想顯示幾個(gè)符合條件的項(xiàng),Vue 也會(huì)把整個(gè)列表遍歷一遍,造成不必要的性能浪費(fèi)。

Vue 3 時(shí)代:v-if 翻身做主人

在 Vue 3 中,v-if 的優(yōu)先級高于 v-for。這意味著:Vue 會(huì)先判斷條件。如果條件不滿足,它壓根就不會(huì)去執(zhí)行循環(huán)。

  • 后果:雖然性能優(yōu)化了,但邏輯可能變得很奇怪——你可能想過濾列表,結(jié)果因?yàn)?v-if 先執(zhí)行,導(dǎo)致你訪問不到循環(huán)里的變量(比如 item.isActive),直接報(bào)錯(cuò)!

? 官方強(qiáng)烈建議:不要把它們寫在同一個(gè)標(biāo)簽上!

? 最佳實(shí)踐(無論 Vue 2 還是 3)

方法一:用計(jì)算屬性(Computed)過濾

這是最優(yōu)雅、性能最好的寫法。

<!-- 模板里只負(fù)責(zé)展示 -->
<ul>
  <li v-for="user in activeUsers" :key="user.id">
    {{ user.name }}
  </li>
</ul>

<!-- 邏輯里負(fù)責(zé)過濾 -->
<script setup>
import { computed } from 'vue';

const users = ref([...]); // 原始數(shù)據(jù)

// 計(jì)算屬性自動(dòng)過濾出活躍用戶
const activeUsers = computed(() => {
  return users.value.filter(user => user.isActive);
});
</script>

方法二:用 標(biāo)簽包裹

如果你不想用計(jì)算屬性,可以用一個(gè)不可見的 標(biāo)簽來承載 v-for。

<template v-for="user in users" :key="user.id">
  <li v-if="user.isActive">
    {{ user.name }}
  </li>
</template>

?? 總結(jié)一下

特性 v-if v-show v-for
手段 動(dòng)態(tài)添加/移除 DOM 切換 CSS display 循環(huán)生成 DOM
性能 初始渲染開銷小 初始渲染開銷大 需配合 :key
場景 條件不常變 頻繁切換顯示 列表渲染
優(yōu)先級 Vue3 高 / Vue2 低 - Vue2 高 / Vue3 低

一句話口訣

“列表過濾用計(jì)算,頻繁切換用 show,條件渲染用 if,key 值千萬別忘!”

好啦,今天的 Vue 指令大揭秘就到這里!是不是感覺思路清晰多了?趕緊去檢查一下你的代碼,把那些混用的 v-if 和 v-for 改過來吧!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容