virtual dom,虛擬DOM,用JS模似DOM結構。DOM變化的對比,放在JS層來作(圖靈完備語言),提升重繪性能。DOM操做是「昂貴」的,js運行效率高。css
jQuery渲染html
var data = [ { name: "AA", sex: "女", add: "北京" }, { name: "BB", sex: "男", add: "上海" } ] function render(data) { var $container = $('#container') // 清空容器,重要!! $container.html('') // 拼接table var $table = $('<table>') $table.append($('<tr><th>姓名</th><th>性別</th><th>區域</th></tr>')) data.forEach(function(item){ $table.append($('<tr><td>'+ item.name +'</td><td>'+ item.sex +'</td><td>'+ item.add +'</td></tr>')) }) // 渲染到頁面 $container.append($table) } function change() { data[0].add = '朝陽' data[1].name = 'CC' // re-render 再次渲染 render(data) } render(data)
snabbdom渲染node
<div id="container"> </div> <button onclick="change()">change</button> <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.min.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-props.min.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-style.min.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-eventlisteners.min.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/h.js"></script> <script> var data = [ { name: "AA", sex: "女", add: "北京" }, { name: "BB", sex: "男", add: "上海" } ] // 把表頭也放在 data 中 data.unshift({ name: '姓名', sex: '性別', add: '區域' }) var snabbdom = window.snabbdom // 定義 patch var patch = snabbdom.init({ snabbdom_class, snabbdom_props, snabbdom_style, snabbdom_eventlisteners }) // 定義 h var h = snabbdom.h var container = document.getElementById('container') // 渲染函數 var vnode function render(data) { 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] + '')) } } return h('tr', {}, tds ) })) if (vnode) { // re-render patch(vnode, newVnode) } else { // 初次渲染 patch(container, newVnode) } // 存儲當前的 vnode 結果 vnode = newVnode } //初次渲染 render(data) function change () { data[1].add = '朝陽' data[2].name = 'CC' // re-render 再次渲染 render(data) } </script>
核心API:h函數、patch函數算法
.h('<標籤名>',{...屬性...},[...子元素...])app
.h('<標籤名>,',{...屬性...},'...')dom
.patch(container, vnode)函數
.patch(vnode, newVnode)性能
diff算法很是複雜,源碼量很大。spa