测试如下:
<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(" "+_s(message)+" "), _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(" "+_s(message)+" "), _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