用js模拟dom,在js中计算出最小的变更,再操作dom。
通过diff算法层层比较
- 遍历旧的dom树
- 遍历新的dom树
- 排序
时间复杂度O(n^3) 1000节点, 1000000000 不可取的。。。。 冒泡排序,时间复杂度O(n*2)
在vdom的计算中,将时间复杂度降低到了O(n)
只比较同一层级
标签不同,直接删除重建,不再深层比较
标签和key一样,认为是相同的节点,再进行深层次的比较
var snabbdom = require('snabbdom');
// 初始化
var patch = snabbdom.init([ // Init patch function with chosen modules
require('snabbdom/modules/class').default, // makes it easy to toggle classes
require('snabbdom/modules/props').default, // for setting properties on DOM elements
require('snabbdom/modules/style').default, // handles styling on elements with support for animations
require('snabbdom/modules/eventlisteners').default, // attaches event listeners
]);
var h = require('snabbdom/h').default; // helper function for creating vnodes
var container = document.getElementById('container');
function someFn(){
console.log('test someFn....');
}
// 构建虚拟节点
var 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: '/foo'}}, 'I\'ll take you places!')
]);
console.log(vnode);
// Patch into empty DOM element – this modifies the DOM as a side effect
patch(container, vnode);
document.querySelector('#btn').addEventListener('click', function(){
function anotherEventHandler(){
console.log('test anotherEventHandler....');
}
var 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: '/bar'}}, 'I\'ll take you places!')
]);
// Second `patch` invocation
patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state
})