什么是 VNode
我们知道,render function 会被转化成 VNode 节点。虚拟 DOM (Virtual DOM) 其实就是一棵以 JavaScript 对象(VNode 节点) 作为基础的树,用对象属性来描述节点,实际上它是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。由于 Virtual DOM 使以 JavaScript 对象为基础而不依赖真实的平台环境,所以具有跨平台的能力,比如浏览器、Weex、Node 等。
实现一个 VNode
VNode 其实就是一个 JavaScript 对象,只要这个类的一些属性可以直观正确地描述清楚当前节点地信息就行。我们来实现一个简单地 VNode 类
class VNode {
constructor(tag, data, children, text, elm){
/*当前节点的标签名*/
this.tag = tag;
/*当前节点的一些数据信息,比如 props、attrs 等数据*/
this.data = data;
/*当前节点的子节点,是一个数组*/
this.children = children;
/*当前节点的文本*/
this.text = text;
/*当前虚拟节点对应的真实dom节点*/
this.elm = elm;
}
}
现在有一个 vue 组件
<template>
<p class="demo" v-show="isShow">
This is a p.
</p>
</template>
用 JavaScript 代码形式就是这样的
function render () {
return new VNode(
'p',
{
/* 指令集合数组 */
directives: [
{
/* v-show指令 */
rawName: 'v-show',
expression: 'isShow',
name: 'show',
value: true
}
],
/* 静态class */
staticClass: 'demo'
},
[ new VNode(undefined, undefined, undefined, 'This is a p.') ]
);
}
转换成 VNode 以后的情况
{
tag: 'p',
data: {
/* 指令集合数组 */
directives: [
{
/* v-show指令 */
rawName: 'v-show',
expression: 'isShow',
name: 'show',
value: true
}
],
/* 静态class */
staticClass: 'demo'
},
text: undefined,
children: [
/* 子节点是一个文本VNode节点 */
{
tag: undefined,
data: undefined,
text: 'This is a p.',
children: undefined
}
]
}
接着,我们对 VNode进行封装,产生一些常用 VNode 地方法
- 创建一个空节点
function createEmptyVNode () {
const node = new VNode();
node.text = '';
return node;
}
- 创建一个文本节点
function createTextVNode (val) {
return new VNode(undefined, undefined, undefined, String(val));
}
- 克隆一个 VNode 节点
function cloneVNode (node) {
const cloneVnode = new VNode(
node.tag,
node.data,
node.children,
node.text,
node.elm
);
return cloneVnode;
}
总的来说,VNode 就是一个 JavaScript 对象,用 JavaScript 对象的属性来描述当前节点的一些状态,用 VNode 节点的形式来模拟一棵 Virtual DOM 树。
想了解更多详情,请戳https://juejin.im/book/5a36661851882538e2259c0f/section/5a3bb16b6fb9a045167d5e81
网友评论