很多时候,在新手面试的过程中都会问到,vue如何实现数据的双向绑定或是数据响应式原理是什么?
大多数人人只是知道vue的双向绑定采用了js中的Object.defineProperty方法,其中get方法是值读取时触发函数,set是设置值时触发函数,当监听到数据变化的消息通知订阅者,触发相应的监听回调函数
当然这些是很简单的原理理解,也有人把官方描述的原理说了出来
vue的数据双向绑定原理是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty来动持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调函数
以上两种方式的描述,听起来还让人比较难以理解,其实需要实现数据的双向绑定简单的分为三步:
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器
具体代码如下:
//Observer实现如下:
function Observer(data) {
this.data = data;
this.walk(data);
}
Observer.prototype = {
walk: function(data) {
var self = this;
Object.keys(data).forEach(function(key) {
self.defineReactive(data, key, data[key]);
});
},
defineReactive: function(data, key, val) {
var dep = new Dep();
var childObj = observe(val);
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function getter () {
if (Dep.target) {
dep.addSub(Dep.target);
}
return val;
},
set: function setter (newVal) {
if (newVal === val) {
return;
}
val = newVal;
dep.notify();
}
});
}
};
function observe(value, vm) {
if (!value || typeof value !== 'object') {
return;
}
return new Observer(value);
};
function Dep () {
this.subs = [];
}
Dep.prototype = {
addSub: function(sub) {
this.subs.push(sub);
},
notify: function() {
this.subs.forEach(function(sub) {
sub.update();
});
}
};
Dep.target = null;
| 留言与评论(共有 0 条评论) “” |