携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
Vue通过虚拟DOM操作真实DOM来进行数据的更新
当我们在一个Vue页面中声明段HTML代码,并绑定一个变量的时候,页面中展示的内容会根据myTitle数据值的变化实时更新。
<div>{{ myTitle }}<div>
那么在这个过程中发生了什么呢?我们先来看看源码文件的结构。
VNode数据结构
在源码中(/core/vdom/vnode.js)展现了关于Vnode结点的设计,包括属性/样式/事件等等
createElement 创建VNode
在源码中(/core/vdom/create-element.js),通过createElement来创建虚拟节点VNode,虚拟DOM树由无数个虚拟节点组成(也就是VNode),VNode 必须唯一。其中包括:
- 注释节点
- 文本节点
- 元素节点
- 组件节点
- 函数式组件节点
- 克隆节点
createElement调用_createElement(),_createElement()创建vnode对象,返回VNode:
createElement接收5个参数:
- context // 虚拟节点的上下文环境,类型:Component
- tag // 标签
- data // 虚拟节点的数据,类型:VNodeData
- children // 示当前虚拟节点的子节点
- normalizationType // 子节点规范的类型
VNode渲染成DOM
在生命周期中的mounted阶段,会将DOM节点进行挂载,此时的节点都是新节点,会全部渲染。
patch
/core/vdom/patch.ts 文件中,DOM-Diff进行了对新旧的虚拟节点VNode的对比,找到差异后更新到真实DOM,也就是执行diff算法,下文中会详细介绍。
完整流程
模板------->编译------>执行渲染函数----->生成虚拟节点----->createElement(将VNode渲染成DOM节点)----->patch(新旧的虚拟节点对比)----->更新视图
总结
在全局实例对象的初次编译时,Templete内的标签被编译成虚拟节点VNode,并且缓存在内存中,在数据变化时后通过新旧对 && diff算法更新DOM树,视图更新。