面试时候,被问到这样一道题目,v-for和v-if的优先级哪个更高,为什么。以及同时出现v-for和v-if的时候怎么优化性能最好呢?
解决问题最好的方式,当然是实践。
1、当v-if与v-for同级时
// data数据
const data = {
items: [
{ id: 1, name: '吃西瓜' },
{ id: 2, name: '吃柠檬' }
]
}
const app = new Vue({
el: '#demo',
data() {
return data
},
computed: {
isTrue() {
return this.items && this.items.length > 0
}
}
})
// console.log(app.$options.data)
console.log(app.$options.render)
输出渲染函数render是这样的:
ƒ anonymous() {
with(this){return _c('div',{attrs:{"id":"demo"}},_l((items),function(item){return (isTrue)?_c('p',[_v(_s(item.name))]):_e()}),0)}
}
_l是列表渲染函数,输出所有children
return的最终结果是,做的isTrue的判断
从上面的render我们看出,先执行的v-for然后每次v-for中都进行了isTrue的判断(浪费性能)
2、v-if放入template
代码修改一下:
<template v-if="isTrue">
<p v-for="item in items">{{item.name}}</p>
</template>
此时我们再次输出render函数:
ƒ anonymous(
) {
with(this){return _c('div',{attrs:{"id":"demo"}},[(isTrue)?_l((items),function(item){return _c('p',[_v(_s(item.name))])}):_e()],2)}
}
我们看到render函数变化了
v-if被解析为了三元运算符进行了判断:
[(isTrue)?_l((items)
此时先进行的v-if的判断,当为true才会去循环遍历数组(nice!)
从上面两个小demo我们不难发现:
结论:
- v-for的优先级要高于v-if
- 当两者同时出现,我们要将v-if提取出来,用一个template标签
- 当列表中每一项带有显隐字段,不得不同时嵌套v-if时候,可以用计算属性先过滤一下
3、查看一下源码
github地址在这里:https://github.com/vuejs/vue
我们找到文件:complier/codegen/index.js
我们看节点顺序是这样的:静态节点、once、for、if
通过源码我们也可以看到v-for的优先级是高于v-if的
4、循环列表项中存在显隐属性
当list中存在某个属性isTrue来控制渲染时候,我们需要在computed中计算一下将需要渲染的留下即可,这样可以起到性能优化的作用
demo的git地址:https://github.com/taoorange/vue2-knowledge-points.git
视频地址: