avatar
fireworks99
keep hungry keep foolish

From jQuery to MVVM & virtual DOM

MVVM模式是因何而生的?Virtual DOM是什么?

JavaScript操作DOM

<div id="js">
  <h2>JavaScript</h2>
  <p>Hello, <span class="name">Bart</span>!</p>
  <p>You are <span class="age">12</span>.</p>
  <button onclick="JSModify()">修改</button>
</div>

<script>
    let name = "Jessica";
    let age = 33;

    function JSModify(){
      document.getElementById("js")
          .getElementsByClassName("name")[0].innerText = name;
      document.getElementById("js")
          .getElementsByClassName("age")[0].innerText = age;
    }
</script>

jQuery操作DOM

JavaScript是一个操作DOM的工具,jQuery让这个工具变得更好用。

假设DOM是一颗子弹,那么可以认为JavaScript是一把枪,用JavaScript这把枪发射DOM这颗子弹时声音太大,这是一个弊端(会引起敌人的注意),于是诞生了jQuery这样的消音器。jQuery没有创造出新的东西,但它让JavaScript更好用了。

<div id="jQ">
  <h2>jQuery</h2>
  <p>Hello, <span class="name">Bart</span>!</p>
  <p>You are <span class="age">12</span>.</p>
  <button onclick="jQModify()">修改</button>
</div>

<script src="../js/jquery-3.5.1.js"></script>
<script>
  let name = "Jessica";
  let age = 33;

  function jQModify(){
      $("#jQ .name:first").text(name);
      $("#jQ .age:first").text(age);
  }
</script>

MVVM操作DOM

总结业务需求:数据(Model)发生了改变,视图(View)跟着改变。

前面两种方式都是,当数据(Model)发生变化时,手动操作DOM,改变视图(View)。

而通过业务需求可知,如果能做一个东西使得数据(Model)与视图(View)两者进行绑定,那么当一者更新了,另一者就跟着自动更新了,就省去了手动操作DOM的过程。

MVVM模式应运而生:设计一个ViewModel将Model与View进行绑定,当数据(Model)发生变化时,不再手动操作DOM,而是其自动修改DOM。

如此一来,把开发人员从“操作DOM”这一复杂繁琐的工作中拯救出来。

<div id="app">
  <h2>MVVM</h2>
  <p>Hello, <span id="name">{{name}}</span>!</p>
  <p>You are <span id="age">{{age}}</span>.</p>
  <button @click="VueModify">修改</button>
</div>

<script src='../js/vue.js'></script>
<script>
  let name = "Jessica";
  let age = 33;

  const app = new Vue({
    el: "#app",
    data: {
      name: "Bart", 
      age: 12
    },
    methods: {
      VueModify(){
        this.name = name;
        this.age = age;
      }
    }
  });
</script>

补充:Virtual DOM

当数据(Model)发生变化时:

  • MVVM模式大大简化了操作DOM(来改变视图View)这一工作
  • 另外还有一种简化操作DOM(来改变视图View)的方法,那就是:用模板引擎重新渲染整个视图替换旧视图

(这里具体如何实现我不理解)

但重新构建一整个DOM Tree会很慢,而Virtual DOM解决了这一问题。

Virtual DOM 是位于 JS 与 DOM 之间的一个过渡,Virtual DOM 算法步骤如下:

  1. 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
  2. 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
  3. 把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了

这样一来实现了用操作 JS 对象来替代操作DOM,会快很多。

参考链接:

[1] Liao Xue-Feng, MVVM[EB/OL]. https://www.liaoxuefeng.com/wiki/1022910821149312/1108898947791072

[2] livoras, How to implement a Virtual DOM algorithm[EB/OL]. https://github.com/livoras/blog/issues/13

Site by Baole Zhao | Powered by Hexo | theme PreciousJoy