首页 / VUE / vue更新dom的diff算法
vue更新dom的diff算法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了vue更新dom的diff算法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2896字,纯文字阅读大概需要5分钟。
内容图文
![vue更新dom的diff算法](/upload/InfoBanner/zyjiaocheng/634/d9d7894c25454080a821feb5d1e6b9f0.jpg)
diff算法使只更新我们修改的那一小块dom而不要更新整个dom:
在采取diff算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较:
判断是否是相同节点:
function sameVnode (a, b) { return ( a.key === b.key && // key值 a.tag === b.tag && // 标签名 a.isComment === b.isComment && // 是否为注释节点 // 是否都定义了data,data包含一些具体信息,例如onclick , style isDef(a.data) === isDef(b.data) && sameInputType(a, b) // 当标签是<input>的时候,type必须相同 ) }
如果两个节点是一样的,那么就深入检查他们的子节点。如果两个节点不一样那就可以直接替换oldVnode
:
function patch (oldVnode, vnode) { // some code if (sameVnode(oldVnode, vnode)) { patchVnode(oldVnode, vnode) // 相同节点打补丁 } else { const oEl = oldVnode.el // 当前oldVnode对应的真实元素节点 let parentEle = api.parentNode(oEl) // 父元素 createEle(vnode) // 根据Vnode生成新元素 if (parentEle !== null) { api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl)) // 将新元素添加进父元素 api.removeChild(parentEle, oldVnode.el) // 移除以前的旧元素节点 oldVnode = null } } // some code return vnode }
当我们确定两个节点相同之后我们会对两个节点执行patchVnode
方法:
patchVnode (oldVnode, vnode) { const el = vnode.el = oldVnode.el let i, oldCh = oldVnode.children, ch = vnode.children if (oldVnode === vnode) return if (oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text) { api.setTextContent(el, vnode.text) }else { updateEle(el, vnode, oldVnode) if (oldCh && ch && oldCh !== ch) { updateChildren(el, oldCh, ch) }else if (ch){ createEle(vnode) //create el's children dom }else if (oldCh){ api.removeChildren(el) } } }
这个函数做了以下事情:
- 找到对应的真实dom,称为
el
- 判断
Vnode
和oldVnode
是否指向同一个对象,如果是,那么直接return
- 如果他们都有文本节点并且不相等,那么将
el
的文本节点设置为Vnode
的文本节点。 - 如果
oldVnode
有子节点而Vnode
没有,则删除el
的子节点 - 如果
oldVnode
没有子节点而Vnode
有,则将Vnode
的子节点真实化之后添加到el
- 如果两者都有子节点,则执行
updateChildren
函数比较子节点,这一步很重要
updateChildren
不设key,newCh和oldCh只会进行头尾两端的相互比较,设key后,除了头尾两端的比较外,还会从用key生成的对象oldKeyToIdx
中查找匹配的节点,所以为节点设置key可以更高效的利用dom。
先进行4种比较:
如果是oldS和E相同,那么真实dom中的第一个节点会移到最后;
如果是oldE和S相同,那么真实dom中的最后一个节点会移到最前;
如果oldS和S相同,会调用patchVnode方法,继续判断这两个节点的子节点,oldStartIndex,newStartIndex指向下个节点;
如果oldE和E相同,会调用patchVnode方法,继续判断这两个节点的子节点,oldStartIndex,newStartIndex指向上个节点;
如果以上都不匹配,就尝试在oldChildren中寻找跟newStartVnode具有相同key的节点,如果找不到相同key的节点,说明newStartVnode是一个新节点,就创建一个,然后把newStartVnode设置为下一个节点
我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点
如果以上都不行会依次比较如下:
即把C更新成F,D更新成C,E更新成D,最后再插入E
原文:https://www.cnblogs.com/wind-lanyan/p/9061684.html
内容总结
以上是互联网集市为您收集整理的vue更新dom的diff算法全部内容,希望文章能够帮你解决vue更新dom的diff算法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。