自从学完vue之后,我又相继接触了两个vue项目,期间深感自身不足,所以多方学习(技术文章或者相关视频等),也有所收获,特来写此系列文章,一是为了巩固自身学习,二是为了供还有所惑之人参考借鉴,如果文章正好能够解你所惑,那我深感慰藉。
之所以称为面试系列,是因为这些关于vue的知识点皆是面试中能够用到的,就算面试中不提,对于加深vue某方面的理解也是有一定作用的,言虽如此,全凭个人水平高低。
若有大神路过,且文章有不正之处,亦或对此有不同见解者,皆可指正提点,笔者必大感欣喜。
一、vue中v-if和v-for哪个优先级更高?
对于这个问题,其实我们可以在源码中找到答案:
源码文件位置:vue->src->compiler->codegen->index.js中
如图:
上图箭头所指的就是v-for和v-if的执行顺序,我们可以清楚的看到for判断在前,if判断在后,也就是说:v-for是要先于v-if执行的,答案也就是如此。
那么我们来测试一下,看是不是如此:
1. 同层测试:v-if和v-for位于同一元素层上
<div id="demo">
<!-- 同级测试 -->
<p v-for='item in children' v-if="isFolder">{{item.title}}</p>
</div>
<script src="../vuejs/vue.js"></script>
<script>
const app = new Vue({
el: '#demo',
data() {
return {
children: [{
title: 'foo'
}, {
title: 'bar'
}]
}
},
computed: {
isFolder() {
return this.children && this.children.length > 0
}
}
});
// 输出渲染函数
console.log(app.$options.render)
</script>
然后我们看一下,浏览器中的输出情况:
以上这段代码的渲染代码,我们可以清楚的看到有一个_l函数,这个函数就是循环渲染函数,那么在这个函数内部,我们可以看到(isFolder)这个字眼,这就是用来做判断的(也就是我们的判断条件)。
显然,判断条件是循环函数中的;
所以,从上面的代码能够得出的结论就是,每执行一次循环,就会在循环内部做一次判断,而这样做的结果就是,造成了较大的性能开销。
我们继续做测试:
2. v-if和v-for位于不同层元素上:
<div id="demo">
<!-- 不同级测试 -->
<template v-if='isFolder'>
<p v-for="item in children">{{item.title}}</p>
</template>
</div>
<script src="../vuejs/vue.js"></script>
<script>
const app = new Vue({
el: '#demo',
data() {
return {
children: [{
title: 'foo'
}, {
title: 'bar'
}]
}
},
computed: {
isFolder() {
return this.children && this.children.length > 0
}
}
});
// 输出渲染函数
console.log(app.$options.render)
</script>
执行以上代码之后,我们再来看它的渲染代码:
渲染代码如上,此时,我们可以清楚的看到(isFolder)字眼竟然跑到了_l(循环渲染函数)函数之前,这也就意味着,此时的代码渲染,是先做判断,然后再循环,如此一来,就会大大节省代码渲染效率,节省性能。
结论:
1. 经过上述分析,显然v-for要先于v-if被执行,这是重要结论;
2. 如果它们同时出现在一个元素层,那么每次渲染都会先执行循环,然后在执行判断,无论如何,每次循环都不可避免的要执行一次判断,浪费了性能;
3. 要避免出现这种情况,则需要在外层嵌套template,在这一层进行v-if判断,然后在标签内使用v-for进行循环。
注:如有不当之处,敬请指正,感谢您的阅读!