Vue 双向数据绑定原理解析
Vue 双向数据绑定是 Vue 框架中的一种核心机制,实现数据和视图之间的双向绑定。下面是对 Vue 双向数据绑定原理的详细解析。
基本原理
Vue 采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter 和 getter。当数据发生变化时,发布消息给订阅者,触发相应函数的回调。
实现 MVVM
要实现 MVVM 的双向绑定,需要实现以下几点:
1. 实现一个数据监听器 Observer,能够对对象的所有属性进行监听,发生变化时拿到最新值通知订阅者。
2. 实现一个解析器 Compile,对每个子元素节点的指令进行扫描和解析,根据模板指令替换数据,初始化视图以及绑定相应的回调函数。
3. 实现一个 Watcher,作为 Observer 和 Compile 的桥梁,能够订阅属性变动的通知,执行指令绑定的回调函数,更新视图。
4. MVVM 的入口,整合以上三者流程图如下:
MVVM.js
MVVM.js 是 MVVM 的入口文件,整合 Observer/Compile/Watcher 三者,达到数据变化->更新视图;视图变化->数据变更的双向绑定效果。
```javascript
function MVVM(options) {
this.$options = options || {};
var data = this._data = this.$options.data;
var me = this;
// 数据代理
// 实现 vm.xxx -> vm._data.xxx
Object.keys(data).forEach(function(key) {
me._proxyData(key);
});
// 代理计算属性
// 同样通过 Object.defineProperty 进行劫持
this._initComputed();
observe(data, this);
this.$compile = new Compile(options.el || document.body, this);
}
MVVM.prototype = {
$watch: function(key, cb, options) {
new Watcher(this, key, cb);
}
}
```
Observer.js
Observer.js 是数据监听器的实现,能够对对象的所有属性进行监听,发生变化时拿到最新值通知订阅者。
```javascript
function Observer(data) {
Object.keys(data).forEach(function() {
defineReactive(data, key, data[key]);
});
}
function defineReactive (data, key, val) {
var dep = new Dep();
var childObj = observe(val);
Object.defineProperty(data, key, {
enumerable: true, // 可枚举
configurable: false, // 不能再 define
get: function() {
if (Dep.target) {
dep.depend();
}
return val;
},
set: function(newVal) {
if (newVal === val) {
return;
}
val = newVal;
// 新的值是 object 的话,进行监听
childObj = observe(newVal);
// 通知订阅者
dep.notify();
}
});
}
```
Dep.js
Dep.js 是发布者-订阅者模式的实现,每个属性维护一个 Dep,记录自己的订阅者。
```javascript
function Dep() {
this.id = uid++;
this.subs = [];
}
Dep.prototype = {
addSub: function(sub) {
this.subs.push(sub);
},
depend: function() {
Dep.target.addDep(this);
},
notify: function() {
this.subs.forEach(function(sub) {
sub.update();
});
}
}
```
通过上述实现,Vue 实现了双向数据绑定,数据和视图之间可以实时同步,提高了开发效率和用户体验。
- 1
- 2
前往页