測試如下:
<body>
<div id="app">
{{message}}
<ul>
<li v-for="item in list" v-if="item.state === 0">{{item.name}}</li>
</ul>
<ul v-if="isShow">
<li v-for="item in list">{{item.name}}</li>
</ul>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
message: 'Hello World',
isShow: false,
list: [
{ id: 0, name: '小李', state: 0 },
{ id: 1, name: '小紅', state: 0 },
{ id: 2, name: '小王', state: 1 },
{ id: 3, name: '小張', state: 0 }
]
}
})
</script>
</body>
-
兩者同級時的
render
函數(function() { with(this){ return _c('div', {attrs:{"id":"app"}}, [_v("\n "+_s(message)+"\n "), _c('ul',_l((list),function(item){ // _l 列表渲染方法 return (item.state === 0)?_c('li',[_v(_s(item.name))]):_e()}),0)]) } })
當兩者放在一起,
(item.state === 0)
一定是在內部,我們可以看出_l 循環是在外面先執行, -
兩者不同級渲染函數如下:
(function() { with(this){ return _c( 'div', { attrs:{ "id":"app" } }, [ _v("\n "+_s(message)+"\n "), _v(" "),(isShow) ? _c('ul',_l((list), function(item){ return _c('li',[_v(_s(item.name))]) }),0) :_e() ] ) } })
兩者不同級時,
isShow
在_l 渲染函數
外部
我們來看看源碼的實現:vue/src/compiler/codegen/index.js
結論:
- 顯然 v-for優先級高於v-if;
- 兩者同級出現,每次渲染都會先執行循環再判斷條件,無論如何循環都不可避免的浪費性能;
- 避免出現這種情況,可在外層嵌套一層進行v-if判斷,然后在內部進行v-for循環;
- 如果條件出現在循環內部,可通過計算屬性提前過濾掉那些不需要顯示的項,減少dom操作;
注意:官方不推薦在同一元素上使用 v-if
和 v-for