我们知道,render function 会被转化成 VNode 节点。Virtual DOM 其实就是一棵以 JavaScript 对象(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>
<span class="demo" v-show="isShow">
This is a span.
</span>
</template>
用 JavaScript 代码形式就是这样的。
function render () {
return new VNode(
'span',
{
/* 指令集合数组 */
directives: [
{
/* v-show指令 */
rawName: 'v-show',
expression: 'isShow',
name: 'show',
value: true
}
],
/* 静态class */
staticClass: 'demo'
},
[ new VNode(undefined, undefined, undefined, 'This is a span.') ]
);
}
看看转换成 VNode 以后的情况。
{
tag: 'span',
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 span.',
children: undefined
}
]
} 、
总的来说,VNode 就是一个 JavaScript 对象,用 JavaScript 对象的属性来描述当前节点的一些状态,用 VNode 节点的形式来模拟一棵 Virtual DOM 树。