vdom 是什么?为何会存在 vdom?
- virtual dom , 虚拟 DOM
- 用 JS 模拟 DOM 结构
- DOM 操作非常“昂贵”
- 将 DOM 对比操作放在 JS层,提高效率
vdom 如何应用,核心 API 是什么
- 如何使用?可用 snabbdom 的用法来举例
- 核心 API:h 函数、patch 函数
介绍一下 diff 算法
- 知道什么是 diff 算法,是 linux 的基础命令
- vdom 中应用 diff 算法是为了找出需要更新的节点
- 实现,patch(container, vnode) 和 patch(vnode, newVnode)
- 核心逻辑,createElement 和 updateChildren
createElement .js:
function createElement(vnode) {
var tag = vnode.tag // 'ul'
var attrs = vnode.attrs || {}
var children = vnode.children || []
if (!tag) {
return null
}
// 创建真实的 DOM 元素
var elem = document.createElement(tag)
// 属性
var attrName
for (attrName in attrs) {
if (attrs.hasOwnProperty(attrName)) {
// 给 elem 添加属性
elem.setAttribute(attrName, attrs[attrName])
}
}
// 子元素
children.forEach(function (childVnode) {
// 给 elem 添加子元素
elem.appendChild(createElement(childVnode)) // 递归
})
// 返回真实的 DOM 元素
return elem
}
updateChildren:
function updateChildren(vnode, newVnode) {
var children = vnode.children || []
var newChildren = newVnode.children || []
children.forEach(function (childVnode, index) {
var newChildVnode = newChildren[index]
if (childVnode.tag === newChildVnode.tag) {
// 深层次对比,递归
updateChildren(childVnode, newChildVnode)
} else {
// 替换
replaceNode(childVnode, newChildVnode)
}
})
}
function replaceNode(vnode, newVnode) {
var elem = vnode.elem // 真实的 DOM 节点
var newElem = createElement(newVnode)
// 替换
}