面试官:为什么Vue中的v-if和v-for不建议一起用-
面试官:为什么Vue中的v-if和v-for不建议一起使用?只有当指令的表达式返回真值时,才会渲染这段内容。v-for指令基于数组呈现列表。v-for指令需要使用iteminitems形式的特殊语法,其中items是源数据数组或对象,item是要迭代的数组元素的别名。使用v-for时,建议设置key值,保证每个key值唯一,方便diff算法优化两者的使用{{item.label}}2.优先级v-if和v-for都是vue模板系统中的指令。vue模板在编译时,指令系统会转化为可执行的渲染函数示例。写一个p标签,同时使用v-if和v-for{{item.title}}
<
创建一个vue实例来存储isShow和items数据constapp=newVue({el:"#app",data(){return{items:[{title:"foo"},{title:"baz"}]}},computed:{isShow(){returnthis.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放在不同的标签
{{item.title}} 然后输出渲染函数?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的源码位置:\\vue-dev\\src\\compiler\\codegen\\index.jsexportfunctiongenElement(el:ASTElement,state:CodegenState):字符串{if(el.parent){el.pre=el.pre||el.parent.pre}if(el.staticRoot&&!el.staticProcessed){returngenStatic(el,state)}elseif(el.once&&!el.onceProcessed){returngenOnce(el,state)}elseif(el.for&&!el.forProcessed){returngenFor(el,state)}elseif(el.if&&!el.ifProcessed){returngenIf(el,state)}elseif(el.tag==='模板'&&!el.slotTarget&&!state.pre){returngenChildren(el,state)||'void0'}elseif(el.tag==='slot'){returngenSlot(el,state)}else{//组件或元素...}判断if时,v-for先于v-判断如果。最终结论:v-for比v-if有更高的优先级。注意事项千万不要把v-if和v-for同时用在同一个元素上,造成性能浪费(每次渲染都会先循环再做条件判断)。如果避免这种情况,在外层嵌套模板(页面渲染不生成dom节点),在这一层进行v-if判断,然后在
内部进行v-for循环如果条件出现在循环内部,可以通过computed属性提前过滤掉不需要显示的itemscomputed:{items:function(){returnthis.list.filter(function(item){returnitem.isShow})}}去前端面试题库查看更多