码迷,mamicode.com
首页 > 其他好文 > 详细

虚拟dom应用

时间:2019-06-16 09:40:04      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:nod   更新   展示   color   例子   事件   span   char   prope   

vdom如何应用,核心api是什么
1、介绍snabbdom(开源社区用的多,vue2用的是他)
首先回顾下之前的vdom格式
真实的dom
<body>
  <ul id="list">
    <li class="item">item 1</li>
    <li class="item">item 2</li>
  </ul>
</body>

 

 

js模拟的dom
{
  tag: ‘ul‘,
  attrs: {
    id: ‘list‘
  },
  children:[{
    tag: ‘li‘,
    attrs: { className: ‘item‘ },
    children: [‘item 1‘]
  },{
    tag: ‘li‘,
    attrs: { className: ‘item‘},
    children:[‘item 2‘]
  }]
}

用js模拟的体量非常小。

 

技术图片

看snabbdom里面的介绍。一个h函数,一个patch函数,就是vdom最主要的api。看h函数传的是什么。

第一个是标签div,标签对应的id #container,标签对应的class,two,classes。
第二个参数是,这个标签绑定了一个事件,函数叫someFn。
第三个是个数组,数组又是h函数,传入标签,属性,文本
第一次渲染是全部渲染到浏览器中,第二次渲染,数据源有所改变,根据改变重新生成一个newVnode,这个时候再patch。这个时候patch的时候,会进行一个对比,这个对比是只找出需要更新的那部分来更新

 

上面例子的模拟
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
  </head>
  <body>
    <div id="container"></div>
    <button id="btn-change">change</button>

    <!-- 这里版本要一致 -->
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-class.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-props.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-style.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-eventlisteners.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/h.js"></script>

    <script>
      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);
      // 生成vnode
      var vnode = h(ul#list, {}, [
        h(li.item, {}, item 1),
        h(li.item, {}, item 2)
      ])

      patch(container, vnode);

      //模拟改变
      var btnChange = document.getElementById(btn-change);
      btnChange.addEventListener(click, function(){
        var newVnode = h(ul#list, {}, [
          h(li.item, {}, item 1),
          h(li.item, {}, item b),
          h(li.item, {}, item 3)
        ]);
        patch(vnode, newVnode);
      })
    </script>
  </body>
</html>

item1没有渲染,item b, item3闪烁了



2、重做之前的demo

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="container"></div>
  <button id="btn-change">change</button>
 
  <!-- 这里版本要一致 -->
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-class.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-props.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-style.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-eventlisteners.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/h.js"></script>

  <script>
    var snabbdom = window.snabbdom;

    // 定义patch
    var patch = snabbdom.init([
      snabbdom_class,
      snabbdom_props,
      snabbdom_style,
      snabbdom_eventlisteners
    ])
 
    // 定义h
    var h = snabbdom.h;

    // 将该数据展示成一个表格。然后随便修改一个信息,表格也跟着修改
    var data = [{
      name: 张三,
      age: 20,
      address: 北京
    },{
      name: 李四,
      age: 21,
      address: 上海
    },{
      name: 王五,
      age: 22,
      address: 广州
    }];
 
    data.unshift({
      name: 姓名,
      age: 年龄,
      address: 地址
    });

    var container = document.getElementById(container);
    var btnChange = document.getElementById(btn-change);
 
    // 渲染函数
    var vnode;
    function render(data) {
      var newVnode = h(table,{}, data.map(function(item){
        var tds = [];
        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 = newVnode;
    }
    render(data);

    btnChange.addEventListener(click, function(){
      data[1].age = 30;
      data[2].address = 深圳;
      // re-render
      render(data);
    })
  </script>
</body>
</html>

再查看dom,不再是整个table渲染。就只更新改变的dom。



3、核心api
  h(‘<标签名>‘, {...属性}, [...子元素])
  h(‘<标签名>‘, {...属性}, ‘...‘)
 
  patch(container, vnode)
  patch(vnode, newVnode)

 

虚拟dom应用

标签:nod   更新   展示   color   例子   事件   span   char   prope   

原文地址:https://www.cnblogs.com/wzndkj/p/11029589.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!