vue虚拟dom
1.为什么要用虚拟dom 答:因为操作真实dom消耗比较大 为了避免不必要的DOM操作 2.什么是虚拟dom 答:就是将真实的dom转换成 对象key value的形式
hello world
===>
- vnode使用什么方式 避免了不必要的dom操作 答:双指针比对 暴力比对
3.1 双指针比对
- 旧前 新前 dom 比对
- 旧后 新后 dom 比对
- 旧前 新后 dom 比对
- 旧后 新前 dom 比对
3.2 暴力比对
- 根据oldVnode 生成 map表 map[oldVnode.key] = idx
- if newVnode 在 oldVnode 中不存在 那么 新创建newVnode 插入到当前oldChild前面
- if newVnode 在 oldVnode 中存在 将 oldVnode 插入到当前oldChild前面 并且清空 map 对照表中的key
3.3 双指针比对 + 暴力比对 后
if 旧前指针 > 旧后指针 说明新节点比旧节点多 依次append 新元素 if 新前指针 > 新后指针 说明新节点比旧节点少 依次remove 旧元素
vue 真实dom 转换为 虚拟dom
- 首先将真实dom 转换为 ast 语法树
<div id="app" style="red">hello{{msg}}</div>
=>
{"tag":"div", "attrs":[{"name":"id","value":"app"},{"name":"style","value":"color:red"}], "children":[{"type":3,"text":"hello{{msg}}"}],"type":1}
=>
let code = _c('div',{id:"app",style:{"color":"red"}},_v("hello"+_s(msg)))
- 通过 with方法 转换为虚拟dom
function _c(tag, data = {}, ...children) {
return vnode(tag, data, data.key, children);
}
function _v(text) {
return vnode(undefined, undefined, undefined, undefined, text);
}
function _s(text) {
return val === null
? ""
: typeof val === "object"
? JSON.stringify(val)
: val;
}
function vnode(tag, data, key, children, text) {
return {
tag,
data,
key,
children,
text,
};
}
new Function('with(this){return ${code}}')
附图