浅谈 Virtual Dom 的那些事

Posted fuguy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈 Virtual Dom 的那些事相关的知识,希望对你有一定的参考价值。

背景

我们都知道频繁的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>

解决

  1. virtual dom,虚拟 DOM
  2. 用 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 的那些事的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Objective-C中的block那些事

浅谈flask与ctf那些事

浅谈分布式事务那些事

浅谈mysql数据库分库分表那些事

JS之DOM那些事

关于DOM的那些事