Vue源码解析

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根实例在全局中只能有一个,不需要使用函数定义

你可能感兴趣的:(Vue源码解析)