虚拟dom应用

news/2024/7/16 8:35:21
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模拟的体量非常小。

 

https://github.com/snabbdom/snabbdom

看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)

 

转载于:https://www.cnblogs.com/wzndkj/p/11029589.html


http://www.niftyadmin.cn/n/3369855.html

相关文章

C#编程的一般注意事项

区分大小写 所有变量和关键字都是区分大小写的。 命名约定 ECMA标准提供了C#代码所要遵循的命名约定原则。通过遵循严格的命名策略&#xff0c;不仅可以增强程序的一致性&#xff0c;而且可以最大程度地减少通常因随意命名而导致的大小写错误。表2ˉ1对一些较为重要的建议做了…

c 语言基础教程答案,C 语言基础教程(我的C之旅开始了)[九]

1. 自增运算符(Increment Operator)自增运算符 使操作数的值增 1。 可以置于操作数前面&#xff0c;也可以放在后面。例如&#xff1a;n ;n ;这两个语句产生的结果都是使 n 增 1&#xff0c;可以说没什么区别。使用以下语句得到的效果也是一样的&#xff1a;n n 1 ;尽管上面…

C# 布局容器类

从ContainerControl类继承的子类作为容器窗体&#xff0c;可以容纳除Form类对象外的其余窗体对象。 在所有容器窗体内&#xff0c;最基本的就是顶级容器Form类以及面板容器Panel类。这两者的主要区别为&#xff1a;前者具有Windows标准框架&#xff08;标题栏&#xff0c;最大 …

课程学习 - 人类疾病导论 | Introduction To Human Disease

完美人类假设&#xff1a;一类人&#xff0c;具有最完美的基因组&#xff0c;享受最健康的环境和饮食&#xff0c;同时拥有最健康的思想情绪&#xff0c;最终以最长的寿命&#xff0c;自然死亡。 自然死亡是自然生命最终的归宿&#xff0c;这是写在目前基因组里的铁律&#xff…

c语言串口数据解码软件,请高手指教 红外串口解码 返回的数据乱码

已结贴√问题点数&#xff1a;2 回复次数&#xff1a;2请高手指教 红外串口解码 返回的数据乱码刚做了个红外遥控解码,初学编程,写入C51程序如下,通过串口助手调试返回的遥控数据无规则,请哥哥姐姐们指点#include"reg52.h"#define uchar unsigned char#define uint u…

软工团队答辩

1.队员信息&#xff1a; 陈雄 学号&#xff1a;1700509024 博客园链接&#xff1a;https://www.cnblogs.com/bearchan/ 廖鹏辉 学号&#xff1a;1700802007 博客园链接&#xff1a;https://www.cnblogs.com/liaopenghui/ 王生睿  学号&#xff1a;1700802028 博客园链接…

C语言大程序50行,C语言非常简单的字符统计程序50行

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼该程序用于实现linux系统中wc命令的最简单模式wc 命令用于统计文件中字符信息。[xxlocalhost 1.5]$ wc 01.c 02.c 03.c15 23 131 01.c13 18 127 02.c14 20 128 03.c42 61 386 总用量使用c语言写出这种小程序。/** Name: count.c* T…

怎么从git分支上下载代码

1. 在工作空间&#xff0c;右键&#xff0c;打开Git Bash 2. clone主分支的代码&#xff08;即下载主分支代码的过程&#xff09;执行命令&#xff1a; git clone xxx.git3. 进入工程目录cd xxx 4.I believe this occurs when you are trying to checkout a remote branch th…