淺談 Virtual Dom 的那些事
阿新 • • 發佈:2018-06-24
https 操作 封裝 In true 解決 port false his
背景
我們都知道頻繁的dom給我們帶來的代價是昂貴的,例如我們有時候需要去更新Table 的部分數據,必須去重新重繪表格,這代價實在是太大了,相比於頻繁的手動去操作dom而帶來性能問題,vdom很好的將dom做了一層映射關系,進而將在我們本需要直接進行dom的一系列操作,映射到了操作vdom.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>virtualDom</title> </head> <body> <div id="container"></div> <button id="btn-change">修改</button> <script type="application/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script type="application/javascript"> const dataSource = [{ key: ‘1‘, name: ‘胡彥斌‘, age: 32, address: ‘西湖區湖底公園1號‘ }, { key: ‘2‘, name: ‘胡彥祖‘, age: 42, address: ‘西湖區湖底公園1號‘ }]; const columns = [{ title: ‘姓名‘, dataIndex: ‘name‘, key: ‘name‘, }, { title: ‘年齡‘, dataIndex: ‘age‘, key: ‘age‘, }, { title: ‘住址‘, dataIndex: ‘address‘, key: ‘address‘, }]; function render(data) { var container = $(‘#container‘); container.html(‘‘); //清空容器 //添加表頭 var $table =$(‘<table>‘) $table.append($(‘<tr>‘)) columns.map(function(item,index){ $table.append($(‘<td>‘+item.title+‘</td>‘)) }) $table.append($(‘</tr>‘)) //添加表體 dataSource.forEach(function(item){ $table.append($(‘<tr></tr><td>‘+item.name+‘</td>‘+‘<td>‘+item.age+‘</td>‘+‘<td>‘+item.address+‘</td></tr>‘)) }) //只渲染一遍dom,盡然如此,還是需要清空容器 container.append($table) } $(‘#btn-change‘).click(function(){ dataSource[0].name="胡軍網"; dataSource[1].address=‘南山區沙河東路1號‘ //re——render render(dataSource) }) render() </script> </body> </html>
解決
- virtual dom,虛擬 DOM
- 用 JS 模擬 DOM
什麽是vdom
HTML DOM 結構:
<ul id="ul-list"> <li class="item">Item 1</li> <li class="item">Item 2</li> <li class="item">Item 3</li> </ul>
針對於上面HTML DOM 結構,可以用JS表示為:
var ulE = { tagName: ‘ul‘, // 標簽名 props: { // 屬性用對象存儲鍵值對 id: ‘ul-list‘ }, children: [ // 子節點 {tagName: ‘li‘, props: {className: ‘item‘}, children: ["Item 1"]}, {tagName: ‘li‘, props: {className: ‘item‘}, children: ["Item 2"]}, {tagName: ‘li‘, props: {className: ‘item‘}, children: ["Item 3"]}, ] }
JS對象中抽取公共的部分屬性,進一步封裝:
export default Ele = (tagName, props, children) => { this.tagName = tagName this.props = props this.children = children }
import * as el from ‘ele‘; var ol = el(‘ul‘, {id: ‘ul-list‘}, [ el(‘li‘, {className: ‘item‘}, [‘Item 1‘]), el(‘li‘, {className: ‘item‘}, [‘Item 2‘]), el(‘li‘, {className: ‘item‘}, [‘Item 3‘]) ]);
淺談 Virtual Dom 的那些事