虚拟 dom 原理是啥?手写一个简单的虚拟 dom 实现?
vdom 概念
用 JS 模拟 DOM 结构。DOM 变化的对比,放在 JS 层来做。提升重绘性能。
比如有 abc 三个 dom, 如果我们要删除 b dom, 以前浏览器的做法是 全部删除 abc dom , 然后 在添加 b dom 。这样做的成本会非常高。
用 JS 模拟 dom
例如下面的一个 dom 结构:
<ul> <li class="item">item1</li> <li class="item">item2</li> </ul>
这样的 dom 结构,可以模拟为下面的 JS :
let dom = { tag: 'ul', attrs: { id: 'list' }, children: [ { tag: 'li', attrs: {className: 'item'}, children: ['item1'] }, { tag: 'li', attrs: {className: 'item'}, children: ['item2'] } ] }
浏览器操作 dom 是花销非常大的。执行 JS 花销要小非常多,所以这就是为什么虚拟 dom 出现的一个根本原因。
jquery 实现 virtual-dom
一个需求场景
1、数据生成表格。 2、随便修改一个信息,表格也会跟着修改。
<body> <div></div> <br> <button>change</button> <script> let data = [ { name: 'yanle', age: '20', address: '重庆' }, { name: 'yanle2', age: '25', address: '成都' }, { name: 'yanle3', age: '27', address: '深圳' } ]; // 渲染函数 function render(data) { let $container = document.getElementById('container'); $container.innerHTML = ''; let $table = document.createElement('table'); $table.setAttribute('border', true); $table.insertAdjacentHTML('beforeEnd', `<tr> <td>name</td> <td>age</td> <td>address</td> </tr>`); data.forEach(function (item) { $table.insertAdjacentHTML('beforeEnd', `<tr> <td>${item.name}</td> <td>${item.age}</td> <td>${item.address}</td> </tr>` ) }); $container.appendChild($table); } // 修改信息 let button = document.getElementById('btn-change'); button.addEventListener('click', function () { data[1].name = '徐老毕'; data[1].age = 30; data[1].address = '深圳'; render(data); }); render(data); </script> </body>
实际上上面的这段代码也是不符合预期的,因为每次使用 render 方法,都会全部渲染整个 table, 但是并未没有只渲染我们想要的第二行。
遇到的问题:
DOM 操作是非常 昂贵 的, JS 运行效率高。虚拟 dom 的核心就是 diff 算法,对比出不同的 dom 数据,定点渲染不同的数据。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论