?🌈個人主頁:前端青山
🔥系列專欄:Vue篇
🔖人終將被年少不可得之物困其一生
依舊青山,本期給大家帶來vue篇專欄內容:vue中v-if與v-for的優先級?
目錄
v-if和v-for的優先級是什么?
一、作用
二、優先級
示例
注意事項
v-if 與 v-for 同時存在于一個元素上,會發生什么?
vue3中
vue2中
當我們在使用Vue.js開發應用程序時,經常會遇到需要根據條件顯示或隱藏元素的情況。Vue.js提供了v-if
和v-for
指令來實現這一功能。然而,當這兩個指令同時存在于同一個元素上時,我們需要了解它們的優先級,以便正確地控制元素的顯示與隱藏。
在Vue.js中,v-for
指令用于循環渲染元素列表,而v-if
指令用于條件性地渲染元素。當這兩個指令同時存在于一個元素上時,Vue.js將按照一定的優先級來解析它們。
v-if和v-for的優先級是什么?
一、作用
v-if
指令用于條件性地渲染一塊內容。這塊內容只會在指令的表達式返回 true
值的時候被渲染
v-for
指令基于一個數組來渲染一個列表。v-for
指令需要使用 item in items
形式的特殊語法,其中 items
是源數據數組或者對象,而 item
則是被迭代的數組元素的別名
在 v-for
的時候,建議設置key
值,并且保證每個key
值是獨一無二的,這便于diff
算法進行優化
兩者在用法上
<Modal v-if="isShow" />
?
<li v-for="item in items" :key="item.id">{{ item.label }}
</li>
二、優先級
v-if
與v-for
都是vue
模板系統中的指令
在vue
模板編譯的時候,會將指令系統轉化成可執行的render
函數
示例
編寫一個p
標簽,同時使用v-if
與 v-for
<div id="app"><p v-if="isShow" v-for="item in items">{{ item.title }}</p>
</div>
創建vue
實例,存放isShow
與items
數據
const app = new Vue({el: "#app",data() {return {items: [{ title: "foo" },{ title: "baz" }]}},computed: {isShow() {return this.items && this.items.length > 0}}
})
模板指令的代碼都會生成在render
函數中,通過app.$options.render
就能得到渲染函數
? anonymous() {with (this) { return _c('div', { attrs: { "id": "app" } }, _l((items), function (item) { return (isShow) ? _c('p', [_v("\n" + _s(item.title) + "\n")]) : _e() }), 0) }
}
_l
是vue
的列表渲染函數,函數內部都會進行一次if
判斷
初步得到結論:v-for
優先級是比v-if
高
再將v-for
與v-if
置于不同標簽
<div id="app"><template v-if="isShow"><p v-for="item in items">{{item.title}}</p></template>
</div>
再輸出下render
函數
? anonymous() {with(this){return _c('div',{attrs:{"id":"app"}},[(isShow)?[_v("\n"),_l((items),function(item){return _c('p',[_v(_s(item.title))])})]:_e()],2)}
}
這時候我們可以看到,v-for
與v-if
作用在不同標簽時候,是先進行判斷,再進行列表的渲染
我們再在查看下vue
源碼
export function genElement (el: ASTElement, state: CodegenState): string {if (el.parent) {el.pre = el.pre || el.parent.pre}if (el.staticRoot && !el.staticProcessed) {return genStatic(el, state)} else if (el.once && !el.onceProcessed) {return genOnce(el, state)} else if (el.for && !el.forProcessed) {return genFor(el, state)} else if (el.if && !el.ifProcessed) {return genIf(el, state)} else if (el.tag === 'template' && !el.slotTarget && !state.pre) {return genChildren(el, state) || 'void 0'} else if (el.tag === 'slot') {return genSlot(el, state)} else {// component or element...
}
在進行if
判斷的時候,v-for
是比v-if
先進行判斷
最終結論:v-for
優先級比v-if
高
注意事項
-
永遠不要把
v-if
和v-for
同時用在同一個元素上,帶來性能方面的浪費(每次渲染都會先循環再進行條件判斷) -
如果避免出現這種情況,則在外層嵌套
template
(頁面渲染不生成dom
節點),在這一層進行v-if判斷,然后在內部進行v-for循環
<template v-if="isShow"><p v-for="item in items">
</template>
? 3.如果條件出現在循環內部,可通過計算屬性computed
提前過濾掉那些不需要顯示的項
computed: {items: function() {return this.list.filter(function (item) {return item.isShow})}
}
v-if 與 v-for 同時存在于一個元素上,會發生什么?
vue3中
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>vue3 v-for v-if優先級</title>
</head>
<body><div id="app"><!-- 審查元素查看優先級:vue3中,v-if的優先級高于v-for --><ul><li v-if="flag" v-for="item in list" :key="item">{{ item }}</li></ul></div>
</body>
<script src="../lib/vue.global.js"></script>
<script>
Vue.createApp({data () {return {list: ['a', 'b', 'c', 'd'],flag: false}}}).mount('#app')
</script>
</html>
vue2中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>vue2 v-for v-if優先級</title>
</head>
<body>
<div id="app"><!-- 審查元素查看優先級:vue2中,v-for的優先級高于v-if --><ul><li v-if="flag" v-for="item in list" :key="item">{{ item }}</li></ul></div>
</body>
<script src="../lib/vue.js"></script>
<script>
new Vue({data: {list: ['a', 'b', 'c', 'd'],flag: false}}).$mount('#app')
</script>
</html>
通過
審查元素
得知:vue3中,v-if的優先級高于v-for
vue2中,v-for的優先級高于v-if
首先,Vue.js會先解析v-for
指令,生成循環的虛擬DOM節點。然后,在每個循環節點上,Vue.js會再次解析v-if
指令,根據條件判斷是否顯示該節點。換句話說,v-for
的循環優先于v-if
的條件判斷。
這意味著,當v-if
和v-for
同時存在于同一個元素上時,元素會先被循環渲染出來,然后在每次循環內部進行條件判斷,決定是否顯示該元素。
這種優先級的設計是為了避免不必要的循環計算,提高性能。如果v-if
的條件判斷放在v-for
循環之外,那么每次循環都會進行一次條件判斷,這可能會影響性能。
因此,在使用v-if
和v-for
時,我們應該根據實際需求,合理地安排它們的位置。如果我們希望根據條件來動態顯示或隱藏循環渲染的元素,應該將v-if
放在v-for
的內部;如果我們只是希望在滿足某個條件時才進行循環渲染,可以將v-if
放在v-for
的外部。
總結起來,v-for
的優先級高于v-if
,因此在同一個元素上使用這兩個指令時,應根據實際需求合理安排它們的位置,以確保程序的正確運行和更好的性能。