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 算法步骤如下:
- 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
- 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
- 把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