vue@2.x 借助了snabbdom
的虚拟DOM能力
snabbdom 是什么?
A virtual DOM library with focus on simplicity, modularity, powerful features and performance.
另外一个虚拟DOM库:virtual-dom 解释了为什么(Motivation)会出现虚拟DOM?
而事实上视图是数据的体现,如果有种方式能够让数据和视图同步,数据变化时视图自动更新而不需要手动更新(数据驱动),对于开发者来说则简化很多工作,只需要关心数据就行。
所以出现了虚拟DOM,作为数据和视图的中间媒介。数据 -> 虚拟DOM -> 真实DOM。
官方参考,官方demo如下
import {
init, classModule, propsModule, styleModule, eventListenersModule, h
} from "../build/index.js";
const patch = init([// Init patch function with chosen modules
classModule, // makes it easy to toggle classes
propsModule, // for setting properties on DOM elements
styleModule, // handles styling on elements with support for animations
eventListenersModule // attaches event listeners
]);
const container = document.getElementById("container");
const vnode = h("div#container.two.classes",
{ on: { click: someFn } },
[
h("span", { style: { fontWeight: "bold" } }, "This is bold"), " and this is just normal text",
h("a", { props: { href: "http://wwww.baidu.com" } },
"_ baidu.com_1")
]
);
function someFn() {
function anotherEventHandler() {
console.log('anotherEventHandler')
}
const newVnode = h("div#container.two.classes",
{ on: { click: anotherEventHandler } },
[
h("span", { style: { fontWeight: "normal", fontStyle: "italic" } }, "This is now italic type"),
" and this is still just normal text",
h("a", { props: { href: "http://wwww.baidu.com" } }, "_ baidu.com_2")
]
);
// Second `patch` invocation
patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state
}
// Patch into empty DOM element – this modifies the DOM as a side effect
patch(container, vnode);
先是调用init
方法,参数是module数组,后面会深入分析内置的各个module
的作用,该函数返回一个patch
函数。patch
(打补丁的意思对吧)方法用来将虚拟DOM同步到视图,patch
函数有两个入参,分别是老的虚拟节点oldVnode和新的虚拟节点vnode。
export function init(modules, domApi, options) {
//...
return function patch(oldVnode, vnode) {
//...
}
}
调用h
函数,该函数用来创建虚拟DOM,后面会看到虚拟DOM具体是什么东西。
export function h(sel, b, c) {
//...
return vnode(sel, data, children, text, undefined);
}
第一次调用patch
函数时,由于oldVnode是真实DOM,此时会先清空该DOM的子孙,而后对比。显然是将我们上述通过h
函数创建的虚拟DOM全部转化为真实DOM挂载到界面上。
此时当我们点击文本时(提供了click事件:someFn),在该点击事件的回调中:看到我们再次通过h
函数创建一个新的虚拟节点,而后调用patch
来对比新老虚拟节点(树),和第一次情况不同,此时的第一个入参是第一次创建的老的虚拟节点(树),此时会真正对比两颗虚拟节点树的差异,而后将差异同步到视图中。
snabbdom/src 目录结构