上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

Vue3源码Block Tree问题

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    636

    主题

    5187

    回帖

    6069

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6069

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-3-21 16:38:08 | 显示全部楼层 | 阅读模式
    <><a id="user-content-" class="anchor" aria-hidden="true" href="#" ><span class="octicon octicon-link"></span></a>>

    前文

    因为Vue3写的时候和源码解析文章也不是特别多

    也是根据一些讲谈和思否的一些文章伴着研究一些小细节

    加上个人编程功底不是特别深,可能存在事实性错误

    请勿当做准确资料看待

    Vue编译

    Vue编译主要变化感觉就是静态作用域提升以及BlockTree,在编译部分也有一定改变

    感觉复杂度和封装更高了一点,但是在元素判断部分相比Vue2有更干净一点

    Block Tree部分之前一直也没有用心研究

    今天后端炸了,终于有个闲暇时间来研究了

    为了便于理解概念,这里大部分都写了伪代码

    我们在render部分

    渲染Vue3大概是这样的

    function renderfunction(){
      return function render(ctx,cache){
         with(ctx){
           return (_openBlock(), _createBlock(_Fragment, null, [_createVNode(.....)]
         }
      }
    }

    其中就存在了_openBlock和createBlock

    这里是为了只存储动态更新部分的vnode,而摒弃静态vnode,从而提高更新效率

    export function openBlock(disableTracking = false) {
      blockStack.push((currentBlock = disableTracking ? null : []))
    }

    openBlock非常简单,仅仅相当于push了一个空数组,该数组为CurrentBlock

    而在_createVnode的函数中,会根据判断条件,对currentBlock进行push,push进去的就是我们的动态vnode

    function _createVNode(args){
      if(xxxx){
        currentBlock.push(vnode)
      }
    }
    

    在_createVNode函数执行完毕后,会把其执行结果都作为参数,再去执行_createBlock

    _createBlock内部会将currentBlock的内容赋值给vnode.dynamicChildren属性上

    然后将blockStack弹出

    设置当前currentBlock为上一级

    之后将本次vnode作为上一级的currentBlock的动态vnode,投入currentBlock中

    function _createBlock(){
       const vnode = createVNode()
       vnode.dynamicChildren = currentBlock
       blockStack.pop()
       currentBlock = blockStack[blockStack.length - 1]
       if (currentBlock) {
        currentBlock.push(vnode)
       }
      return vnode
    }

    最后在更新的过程中

    会根据dynamicChildren判断进行局部更新还是child全部更新

    如果是根据局部动态更新

    则是根据dynamicChildren读取到数据

    遍历dynamicChildren数组

    然后循环调用patch

    这样更新的时候仅与dynamicChildren的数量多少有关

    而与静态节点的数量无关

    这样会提高更新过程的效率

    也就是Block Tree的意义所在

    结语

    每次写这类文章真的是战战栗栗...

    参考

    https://segmentfault.com/a/1190000022442171

    https://www.cnblogs.com/everlose/p/12853402.html

    https://wuchwuw.github.io/vue-next-analysis/runtime-core/vnode.html#vnode

    https://toutiao.io/posts/2cjs75p/preview

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表