美文网首页周分享
vue-diff算法——周分享

vue-diff算法——周分享

作者: 橙汁坤 | 来源:发表于2020-03-06 14:32 被阅读0次

    当数据发生变化时,vue是怎么更新节点的?

    之前,正常用jq等其他库的时候渲染列表都是直接把整个列表数据添加到dom中,即使列表数据新增一条,会把以前的列表全部替换成新的列表数据,当我们需要在各个事件方法中直接操作DOM来达到修改视图的目的。但是当应用一大就会变得难以维护。

    diff算法的优越性到底体现在哪?

    Vue.js将DOM抽象成一个以JavaScript对象为节点的虚拟DOM树,以VNode节点模拟真实DOM,可以对这颗抽象树进行创建节点、删除节点以及修改节点等操作,在这过程中都不需要操作真实DOM,经过diff算法得出一些需要修改的最小单位,再将这些小单位的视图进行更新。这样做减少了很多不需要的DOM操作,它是对真实Dom的一层抽象.

    image.png
    <div>
        <p>123</p>
    </div>
    
    <div>
        <span>456</span>
    </div>
    

    diff算法的比较只会在span层,当数据发生改变时,set方法会让调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图。

    diff算法是通过同层的树节点进行比较而非对树进行逐层搜索遍历的方式,所以时间复杂度只有O(n),是一种相当高效的算法。


    image.png

    diff流程图
    当数据发生改变时,set方法会让调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图。

    • patch函数接收两个参数oldVnode和Vnode分别代表新的节点和之前的旧节点
      1判断两节点是否值得比较,值得比较则执行patchVnode
      2不值得比较则用Vnode替换oldVnode
    • replace
      如果两个节点都是一样的,那么就深入检查他们的子节点。
      如果两个节点不一样那就说明Vnode完全被改变了,如果第一层不一样那么就不会继续深入比较第二层了,就可以直接替换oldVnode。

    • patchVnode
      1找到对应的真实dom,称为el
      2判断Vnode和oldVnode是否指向同一个对象,如果是,那么直接return
      3如果他们都有文本节点并且不相等,那么将el的文本节点设置为Vnode的文本节点。
      4如果oldVnode有子节点而Vnode没有,则删除el的子节点
      5如果oldVnode没有子节点而Vnode有,则将Vnode的子节点真实化之后添加到el
      6如果两者都有子节点,则执行updateChildren函数比较子节点

    相关文章

      网友评论

        本文标题:vue-diff算法——周分享

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