【Vue2.x 源码学习】第二十篇 - 使用真实节点替换原始节点
一,前言
上篇,根据 vnode 虚拟节点创建真实节点,主要涉及以下几点:
vnode 渲染真实节点的步骤
Vue 原型方法 _update 的扩展
patch 方法中的两个步骤:1,创建真实节点;2,替换掉老节点
createElm 实现:根据虚拟节点创建真实节点
本篇,使用真实节点替换原始节点
二,新老节点的替换更新
目前为止,仅是围绕根节点的实现,尚未涉及组件的更新
1,前情回顾
前面,通过 createElm 完成了根据虚拟节点生成真实节点,详细步骤如下:
通过 vnode 中 tag 判断是元素还是文本:文本的 tag 为 undefined
如果当前节点是文本,创建文本真实节点:document.createTextNode(text)
如果当前节点是元素,创建元素真实节点:document.createElement(tag)
当前节点是元素且存在儿子,继续递归创建儿子的真实节点,并添加到对应的父亲中:
children.forEach(child => {el.appendChild(createElm(child))});
4,返回生成的真实节点
下面继续,使用真实节点替换原始节点
2,新老节点的更新方案
那么,如何进行新老节点的替换?
若使用 replace 方法进行 dom 替换,就需要找到父节点,还需要指定用谁替换谁,使用起来不方便
Vue 的实现方式:
1,找到老节点;
2,将新节点插入到老节点之后,新老为兄弟节点;
3,删除老节点;
这种实现的优势是:能够确保在新老节点完成更新后,文档的顺序不变;
3,虚拟节点与真实节点映射
问题:为什么要做真实节点与虚拟节点的映射关系?
当虚拟节点被更新时,便于跟踪并找到与之【vnode】对应的真实节点【el】,完成真实节点的更新操作
代码实现:
将真实节点绑定到 vnode 扩展属性 el 上:
4,实现新老节点的替换
根据新老节点的更新方案:
找到元素的父亲节点
找到老节点的下一个兄弟节点
将新节点插入到老节点的下一个兄弟节点前面
删除老节点
至此,就完成 Vue 文档中的“Create vm.$el and replace 'el' with it”,即完成了 Vue 的初始化流程
后面,当时数组更新时,Vue 将通过 diff 算法进行组件级别的更新,这就需要进行依赖收集
三,结尾
还剩最后 1 篇了,全程没有特别的划水,还算是比较欣慰;
为了让这些文章日后能更有价值,后续还要挨篇优化;
本篇,使用真实节点替换原始节点,主要涉及以下几点:
新老节点的更新方案
虚拟节点与真实节点映射
实现新老节点的替换
下一篇,依赖收集的过程分析
评论