• 虚拟dom应用


    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)
  • 相关阅读:
    Akka(2):Actor生命周期管理
    Akka(1):Actor
    Akka(0):聊聊对Akka的初步了解和想法
    FunDA:一个开源的函数式数据处理工具库,也是Slick的补充
    FunDA(17)- 示范:异常处理与事后处理
    FunDA(16)- 示范:整合并行运算
    FunDA(15)- 示范:任务并行运算
    FunDA(14)- 示范:并行运算,并行数据库读取
    FunDA(13)- 示范:用户自定义操作函数
    thinkjs中自定义sql语句
  • 原文地址:https://www.cnblogs.com/wzndkj/p/11029589.html
Copyright © 2020-2023  润新知