vue2源码刨析

手搓vue2源码地址:

gitee地址:https://gitee.com/obsessed-with-summer/vue2-source-code-analysis.git

数据监听:

代码位置:src/observer

发布者订阅者+Object.defineProperty中的get和set实现数据劫持:

ast语法树解析:

代码位置:src/compile  

主要是通过这个方法生成render函数,其中包括:html解析为ast语法树,ast拼接为字符串,通过该字符串生成rende函数

  

function compileTofunction(el) {
    //1、将html变成ast语法树
    let ast = parseHTML(el);
    //2、将ast语法树遍历拼接成字符串
    let code = generate(ast);
    //3、将字符串变成render函数
    let render = new Function(`with(this){return ${code}}`)
    return render
}

  

通过_render生成虚拟dom:

代码位置:src/Vnode

_update时候,触发_renders生成新的虚拟dom,然后调用patch方法进行新旧dom对比。
patch有两个参数,分别是新旧dom:
  首先进行以下判断:
  • 没有新节点,直接触发旧节点的destory钩子
  • 没有旧节点,说明是页面刚开始初始化的时候,此时,根本不需要比较了,直接全是新建,所以只调用 createElm
  • 旧节点和新节点自身一样,通过 sameVnode 判断节点是否一样,一样时,直接调用 patchVnode 去处理这两个节点
  • 旧节点和新节点自身不一样,当两个节点不一样的时候,直接创建新节点,删除旧节点

  patchVnode做了如下操作:

  • 新节点是否是文本节点,如果是,则直接更新dom的文本内容为新节点的文本内容
  • 新节点和旧节点如果都有子节点,则处理比较更新子节点
  • 只有新节点有子节点,旧节点没有,那么不用比较了,所有节点都是全新的,所以直接全部新建就好了,新建是指创建出所有新DOM,并且添加进父节点
  • 只有旧节点有子节点而新节点没有,就是把所有的旧节点删除,也就是直接把DOM 删除

  两者都有子节点,则通过updateChidren来比较:

  通过双指针的方式,进行头头比较,尾部尾部比较,然后交叉比较,最终暴力对比。

 

posted @ 2023-06-26 16:09  4zero4NotFound  阅读(41)  评论(0编辑  收藏  举报