Vue中的key的作用和工作原理?
源码位置: src/core/vdom/patch.js -updateChildren()
作用: Key的主要作用是高效的更新虚拟dom,源码中在patch的过程中,会执行patchVnode,patchVode过程中会执行updateChildren方法,会更新两个新旧的子元素,通过key可以准确的判断这两个节点是不是同一个,从而避免了频繁更新不同元素,使得整个patch过程中更加高效,减少dom操作。
如果没有设置key,默认key值就是undefined,并且会判断key值是否相等,因为undefined==undefined 返回true,因此会判断两个节点的标签是否相同,所以没有key值,会循环更新dom,消耗性能
Vue中v-for和v-if谁的优先级高?
源码位置:/src/complier/codegen/index.js
<body>
<div id="app">
<p>源码位置:/src/complier/codegen/index.js</p>
<h1>v-for和v-if谁的优先级高?如何正确使用避免性能问题?</h1>
<!-- 第一种同级情况 -->
<p v-for="item in children" v-if="isFolder">{{item.title}}</p>
<!-- 不同级的情况 -->
<!-- <template v-if="isFolder">
<p v-for="item in children">{{item.title}}</p>
</template> -->
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
children: [
{ title: 'foo' },
{ title: 'bar' }
]
},
computed: {
isFolder() {
return this.children && this.children.length > 0
}
},
})
console.log(app.$options.render)
</script>
结论:
1、v-for优先于v-if被解析,源码中的执行顺序 v-for是优先执行
2、如果同级,同时出现,每次渲染都会先执行循环,再判断条件,不管条件是否成立都会执行一次循环,浪费性能
3、避免这种情况出现,则需要在外面嵌套一层template 进行条件判断,内部进行v-for循环
Vue中的data为什么必须是个函数,而根实例没有这个限制?
源码中,数据初始化的时候会校验data的类型
结论: Vue组件可能存在多个实例,如果data使用对象形式定义,会导致共用一个data对象,那么状态变更会影响所有组件实例,
采用函数式定义,在initData时会将其作为工厂函数返回全新的对象,有效规避多个实例之间状态污染的问题。
而vue根实例在全局中只能有一个,不需要使用函数定义