vue2.x双向数据绑定原理解析
什么是双向数据绑定
双向数据绑定是指视图层和数据层之间的数据同步。当数据层中的数据发生变化时,视图层会自动更新;反之,当视图层中用户操作修改了数据时,数据层的数据也会自动更新。
通常而言,双向数据绑定有两种方式,一种是脏值检测(angular.js),另一种则是数据劫持(vue.js)。
本文将介绍 vue2.x 中的数据劫持实现双向数据绑定的原理。
vue2.x 数据劫持实现原理
vue2.x 使用了 Object.defineProperty() 方法来对数据层进行劫持。
下面是一个简单的例子(仅用于说明原理,实际使用中不建议这样写):
let obj = {};
let value;
Object.defineProperty(obj, 'name', {
get() {
console.log('get')
return value;
},
set(newValue) {
console.log('set');
console.log(`old value:${value}`)
value = newValue;
console.log(`new value:${value}`)
}
})
obj.name = 'vue';
console.log(obj.name);
上述代码中,我们通过 Object.defineProperty() 方法来对 obj 对象的 name 属性进行劫持,当我们执行 obj.name = 'vue'
时,会触发 set 方法,当我们获取 obj.name
的值时,会触发 get 方法。
基于以上例子,我们可以看到,我们通过 Object.defineProperty() 方法来监听了数据的变化,那么我们要如何实现视图层的自动更新呢?
实现视图的自动更新
实现视图层的自动更新是本原理的关键。vue2.x 使用了发布-订阅模式来实现数据发生变化时视图的自动更新。
我们来看一个例子:
class Dep {// 订阅器
constructor() {
this.subs = [];
}
// 添加订阅
addSub(sub) {
if (sub && sub.update) {
this.subs.push(sub);
}
}
// 发布消息
notify() {
this.subs.forEach(sub => {
sub.update()
})
}
}
class Watcher {// 观察者
constructor() {
Dep.target = this;
}
// 更新视图
update() {
console.log("update view");
}
}
Dep.target = null;
let obj = {};
let value;
let dep = new Dep();
Object.defineProperty(obj, 'name', {
get() {
console.log('get')
// 添加订阅者
if (Dep.target) {
dep.addSub(Dep.target)
}
return value;
},
set(newValue) {
console.log('set');
console.log(`old value:${value}`)
value = newValue;
console.log(`new value:${value}`)
// 发布通知
dep.notify();
}
})
new Watcher();
obj.name = 'vue';
在上述代码中,我们首先创建了订阅器 Dep 和观察者 Watcher。
当我们获取 obj 对象的 name 属性值时,会触发 get 方法,我们通过 Dep.target = this
来在获取时将观察者 Watcher 添加到了订阅器 Dep 中。当值发生变化时,则会触发 set 方法,通过 dep.notify()
来发布通知,订阅器 Dep 中的每一个观察者 Watcher 就会收到通知并更新视图。
示例
我们来看两个实际的示例来进一步理解。
示例一
html 代码:
<div id="app">
<input type="text" v-model="name">
<p>{{name}}</p>
</div>
js 代码:
var app = new Vue({
el: "#app",
data() {
return {
name: ""
}
}
})
在上述示例中,我们通过 v-model="name"
来绑定输入框与 data 中的 name 属性。当我们在输入框中输入值时,输入框中显示的值和 p 标签中显示的值会自动同步更新。
示例二
html 代码:
<div id="app">
<p>{{name}} </p>
<button v-on:click="updateName"> 更新值 </button>
</div>
js 代码:
var app = new Vue({
el: "#app",
data() {
return {
name: "vue"
}
},
methods: {
updateName() {
this.name = "vue2.x"
}
}
})
在上述示例中,我们通过 v-on:click="updateName"
来绑定按钮的 click 事件与 updateName 方法。当我们点击按钮时,会自动触发 updateName 方法,将 data 中的 name 属性的值更新为 "vue2.x",视图页面中与 name 属性绑定的 p 标签也会自动更新。
至此,本文介绍了 vue2.x 实现双向数据绑定的原理和实现方式,并通过两个示例来展现了实际应用中的具体使用方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue2.x双向数据绑定原理解析 - Python技术站