v-if和v-for是开发中经常会遇到的2个指令,那么在使用的过程中,2者如果同时存在同一个标签上,谁的优先级会更高一点呢?
那么我们从源码的角度去看他
源码位置compiler/codegen/index.js
在genElement
方法中,我们可以看到一些if else的判断
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
let code
if (el.component) {
code = genComponent(el.component, el, state)
} else {
let data
if (!el.plain || (el.pre && state.maybeComponent(el))) {
data = genData(el, state)
}
const children = el.inlineTemplate ? null : genChildren(el, state, true)
code = `_c('${el.tag}'${
data ? `,${data}` : '' // data
}${
children ? `,${children}` : '' // children
})`
}
// module transforms
for (let i = 0; i < state.transforms.length; i++) {
code = state.transforms[i](el, code)
}
return code
}
处理for循环是处于if的上面的,所以我们由此可以判定v-for的优先级是高于v-if的。
那么我们写个demo,在一个p
标签上,同时加上v-for和v-if:
{{item}}
当我们打印vue.$options.render,打印出的函数,我们可以在浏览器中看到一个打印出来的render函数
ƒ anonymous() {
with(this){return _c('div',{attrs:{"id":"demo"}},[_c('h1',[_v("vue中v-if和v-for谁的优先级更高?应该如何正确使用以避免性能问题?")]),_v(" "),
_l((arr),function(item){return (isTrue)?_c('p'):_e()})],2)}
}
我们可以看到,在这里的_l
就是vue中的列表渲染函数,他在执行的时候,是先执行的for循环,在每次循环的时候,去return一个isTrue
,
那我们在写一个demo,同一个标签上不出现v-for和v-if:
{{item}}
同样,我们执行上述的打印操作,浏览器中会打印出下面这个函数
ƒ anonymous() {
with(this){return _c('div',{attrs:{"id":"demo"}},[_c('h1',[_v("vue中v-if和v-for谁的优先级更高?应该如何正确使用以避免性能问题?")]),_v(" "),
(isTrue)?_l((arr),function(item){return _c('p')}):_e()],2)}
}
从第二行代码我们可以看到,vue先执行了一个isTrue
是否存在的判断,再进行了_l
函数的for循环执行。
所以我们可以得出结论,v-for的优先级是高于v-if的,如果两者同时出现的话,那每次循环都会执行v-if,会很浪费性能,我们正确的做法应该是再v-for的外面新增一个模板标签template
,在template上使用v-if
我们经常会遇见这种情况,在v-for的时候,在数组中会有一些需要进行v-if的判断,这种情况下,我们如果先使用computed
将不需要渲染的项过滤出来,那么在进行v-for的时候,循环的就只是需要渲染的项,这也是提升vue性能的一种方式。