MVVM的核心之一就是虚拟dom树,我们这一章节就先构建一个虚拟dom树
首先我们需要创建一个VNode的类
// 当前类的位置是src/vnode/index.js
export default class VNode{
constructor(
tag, // 标签名称(英文大写)
ele, // 对应真实节点
children, // 子节点
text, // 文本内容
data, // 节点数据
parent, // 父节点
nodeType, // 节点类型
key // 节点key
) {
this.tag = tag;
this.ele = ele;
this.children = children;
this.text = text;
this.data = data;
this.parent = parent;
this.nodeType = nodeType;
this.key = key;
this.env = {} // 环境变量
this.instructions = [] // 指令
this.template = [] // 当前节点的模板
}
}
第二步:构建虚拟dom
构建虚拟dom树的操作我们放在mount事件里面,现在需要创建mount.js
import VNode from '../vnode/index'
/**
* 给MiniVue添加挂载方法
* @param {*} MiniVue
*/
export function initMount(MiniVue) {
MiniVue.prototype.$mount = function (el) {
let root = document.getElementById(el)
mount(this, root)
}
}
/**
* 实现mount事件
* @param {*} vm
* @param {*} el
*/
function mount(vm, el) {
console.log('开始挂载')
// 构建虚拟Dom
vm._vnode = constructVnode(vm, el, parent)
// 预备渲染
}
function constructVnode(vm, el, parent) {
let vnode = null;
const tag = el.nodeName
const text = el.textContent.trim()
const data = {}
const nodeType = el.nodeType
const key = ""
vnode = new VNode(tag, el, [], text, data, parent, nodeType, key)
// 递归构建子节点
vnode.ele.childNodes.forEach(child => {
const childNodes = constructVnode(vm, child, vnode)
if(childNodes instanceof Array) {
vnode.children.push(...childNodes)
} else {
vnode.children.push(childNodes)
}
})
return vnode
}
/**
* 获取节点的文本数据(文本节点)
* @param {*} el
*/
function getNodeText(el) {
return el.nodeType === 3 ? el.textContent.trim() : ''
}
init方法里面执行当前mount
我们在浏览器里面可以看到当前构建的虚拟dom树
本章总结:
1.创建虚拟DOM的类
2.给原型添加mount方法,通过根节点el构建虚拟dom
3.构建dom时,使用深度优先搜索算法(反复调用本身方法),获取子节点