先看效果图
<div id="app">
<input v-model="name" type="text">
<h1>{
{name}}</h1>
</div>
<script src="./js/observer.js"></script>
<script src="./js/watcher.js"></script>
<script src="./js/compile.js"></script>
<script src="./js/index.js"></script>
<script>
const vm = new Mvue({
el: "#app",
data: {
name: "我是摩登"
}
});
</script>
数据绑定
在正式开始之前我们先来说说数据绑定的事情,数据绑定我的理解就是让数据M(model)展示到 视图V(view)上。我们常见的架构模式有 MVC、MVP、MVVM模式,目前前端框架基本上都是采用 MVVM 模式实现双向绑定,Vue 自然也不例外。但是各个框架实现双向绑定的方法略有所不同,目前大概有三种实现方式。
- 发布订阅模式
- Angular 的脏查机制
- 数据劫持
而 Vue 则采用的是数据劫持与发布订阅相结合的方式实现双向绑定,数据劫持主要通过 Object.defineProperty
来实现。
Object.defineProperty
这篇文章我们不详细讨论 Object.defineProperty
的用法,我们主要看看它的存储属性 get 与 set。我们来看看通过它设置的对象属性之后有何变化。
var people = {
name: "Modeng",
age: 18
}
people.age; //18
people.age = 20;
上述代码就是普通的获取/设置对象的属性,看不到什么奇怪的变化。
var modeng = {}
var age;
Object.defineProperty(modeng, 'age', {
get: function () {
console.log("获取年龄");
return age;
},
set: function (newVal) {
console.log("设置年龄");
age = newVal;
}
});
modeng.age = 18;
console.log(modeng.age);
你会发现通过上述操作之后,我们访问 age 属性时会自动执行 get 函数,设置 age 属性时,会自动执行 set 函数,这就给我们的双向绑定提供了非常大的方便。
分析
我们知道 MVVM 模式在于数据与视图的保持同步,意思是说数据改变时会自动更新视图,视图发生变化时会更新数据。
所以我们需要做的就是如何检测到数据的变化然后通知我们去更新视图,如何检测到视图的变化然后去更新数据。检测视图这个比较简单,无非就是我们利用事件的监听即可。
那么如何才能知道数据属性发生变化呢?这个就是利用我们上面说到的 Object.definePro