美文网首页
Vue3源码--优化Slot生成

Vue3源码--优化Slot生成

作者: 勤奋的大鱼 | 来源:发表于2020-05-05 02:12 被阅读0次

    Vue2.x中,如果有一个组件传入了slot,那么每次父组件更新的时候,必定会强制使子组件update,造成性能的浪费。这是由于2.x中,组件的插槽会被当成组件的一个普通children,因此在2.x里面的处理就是只要一个component中传入了slot,那么如果父组件更新,必定会update子组件。
    Vue3优化了Slot的生成,使得非动态slot中属性的更新只会触发子组件的更新。动态slot指的是在slot上面使用v-if,v-for,动态slot名字等会导致slot产生运行时动态变化但是又无法被子组件track的操作。(一般来说还是很少在slot上做这种操作的)
    Vue3实现这个优化的逻辑主要是这样的:

    1. 首先还是静态编译时候做的工作,给一个Component打上一个PatchFlag标记---是否是DynamicSlot,这一块的逻辑在compiler-core/src/transforms/transformElement.ts中。
    2. 遇到有传入slot的组件,它的Children不是普通的vnode数组,而是一个slot function的映射表,这些slot function用于在组件中懒生成slot中的vnodes,如下是一个有传入slot的组件生成的render function。
        _createVNode(_component_sub_com, null, {
          // _withCtx使得可以访问父组件的context
          default: _withCtx(() => [
            _createTextVNode(_toDisplayString(_ctx.count), 1 /* TEXT */)
          ]),
          _: 1
        })
    
    1. 在子组件的render函数里面,调用相应的slot生成函数,因此这个slot函数里面的属性都会被当前的组件实例所track。
    2. 以上过程就实现了插槽被正确的组件实例所追踪,最后,关于第一步所打的标记,如果传入的slot是动态slot,那么会在第二步的createVNode函数中传入DynamicSlot的PatchFlag,在虚拟dom的patch过程中,遇到一个组件有DynamicSlot,就和Vue 2.x 一样,随着父组件更新强制更新这个组件。

    相关文章

      网友评论

          本文标题:Vue3源码--优化Slot生成

          本文链接:https://www.haomeiwen.com/subject/bbdeihtx.html