We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DOM操作很慢,操作DOM后会触发浏览器的重排和重绘。
虚拟DOM通过JS模拟DOM结构,来对真实DOM发生的变化保持追踪。
当数据改变时,新生成的Virtual DOM会与旧的Virtual DOM进行对比,通过Diff算法找到区别,这些操作都是在快速的JS中完成的,最后对实际DOM进行最小的DOM操作来完成效果。
// DOM <div id='parent'> <span class="child">item1</span> </div> // Virtual DOM const dom = { tagName: 'div', props: { id: 'parent' }, children: [ {tagName: 'span', props: {class: 'child'}, children: ['item1']} ] }
将Virtual DOM渲染成DOM
Element.prototype.render = function() { // 根据tagName构建真实DOM var el = document.createElement(this.tagName) var props = this.props // 遍历虚拟DOM中的属性 for (var propName in props) { // 获得属性值 var propValue = props[propName] // 为真实DOM添加属性 el.setAttribute(propName, propValue) } var children = this.children || [] // 遍历子元素 children.forEach(function(child) { var childEl = (child instanceof Element) // 如果还是标签元素,则继续渲染 ? child.render() // 文档元素 : document.createTextNode(child) el.appendChild(childEl) }) // 返回所有渲染后的真实DOM return el }
snabbdom 是轻量的 Virtual DOM 实现,代码量少,模块化,结构清晰。
snabbdom 主要的接口有:
示例
// 引入依赖 <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-class.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-props.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-style.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-eventlisteners.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/h.js"></script> // 初始化snabbdom var snabbdom = window.snabbdom; var patch = snabbdom.init([ snabbdom_class, snabbdom_props, snabbdom_style, snabbdom_eventlisteners ]); var h = snabbdom.h; var container = document.getElementById('container'); var data = [{name: 'aaa', age: 20}, {name: 'bbb', age: 30}]; var vnode // 将数据渲染为虚拟DOM函数 function render(data) { // 将后台给的data对象调用h(),返回一个虚拟DOM对象 // re-render时会重新生成,然后和之前生成的Diff var newVnode = h('table', {}, data.map(function(item) { var tds = [] var i for (i in item) { if (item.hasOwnProperty(i)) { tds.push(h('td', {}, item[i] + '')) } } // 在table里面添加tr,tr里面包含所有的td及td包含的内容 return h('tr', {}, tds) })) if (vnode) { // re-render渲染通道 patch(vnode, newVnode) } else { // 初次渲染通道 patch(container, newVnode) } // 替换vnode的值 vnode = newVnode } // 执行初次渲染 render(data) var btn = document.getElementById('btn') btn.addEventListener('click', function() { var data = [{name: 'aaa', age: 20}, {name: 'ccc', age: 40}]; // 只渲染发生修改的地方!!! render(data); })
参考文章:解析 snabbdom 源码
比较innerHTML和Virtual DOM的重绘
Virtual DOM只会对同一层级的元素进行对比,不会跨层级比较。
设置key值可以最大化的利用节点(可以复用节点)。
// 1.构建虚拟DOM var Tree = el('div', {'id': 'container'}, [ el('h1', {style: 'color:blue'}, ['simple virtual dom']) ]) // 2.通过虚拟DOM渲染真正的DOM var root = tree.render() document.body.appendChild(root) // 3.生成新的虚拟DOM var newTree = el('div', {'di': 'container'}, [ el('h1', {style: 'color: red'}, ['simple virtual dom']) ]) // 4.比较两个虚拟DOM的不同,记录差异,将不同的地方都放在patches数组 var pathces = diff(Tree, newTree) // 5.在真正的DOM元素上应用变更 patch(root, patches)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
虚拟DOM
DOM操作很慢,操作DOM后会触发浏览器的重排和重绘。
虚拟DOM通过JS模拟DOM结构,来对真实DOM发生的变化保持追踪。
当数据改变时,新生成的Virtual DOM会与旧的Virtual DOM进行对比,通过Diff算法找到区别,这些操作都是在快速的JS中完成的,最后对实际DOM进行最小的DOM操作来完成效果。
将Virtual DOM渲染成DOM
snabbdom (2018-03-17)
snabbdom 是轻量的 Virtual DOM 实现,代码量少,模块化,结构清晰。
snabbdom 主要的接口有:
示例
参考文章:解析 snabbdom 源码
比较innerHTML和Virtual DOM的重绘
DOM Diff
Virtual DOM只会对同一层级的元素进行对比,不会跨层级比较。
设置key值可以最大化的利用节点(可以复用节点)。
The text was updated successfully, but these errors were encountered: