Vue学习之数据监听Observer类实现
创建脚本文件
文件名:Observer.js
在index.html中引入脚本文件<script src="Observer.js"></script>
创建Observer类,并在构造函数中传入Vue实例的data数据。
class Observer {
constructor(data) {
this.observer(data);
}
// 实现数据变化监听
observer(data) {
}
}
在MyVue.js中构造Vue实例时初始化Observer类
class MyVue {
// 构造函数
constructor(options) {
this.$el = options.el;
this.$data = options.data;
this.$options = options;
if (this.$el) {
//-----------------------------------------
// 实现数据监听类
new Observer(this.$data);
//-----------------------------------------
// 实现指令解析类
new Compile(this.$el, this);
}
}
}
接下来实现对vue中data的数据劫持
// 实现数据变化监听
observer(data) {
console.log(data);
// 判断数据是否为对象并处理
if (data && typeof data === 'object') {
// console.log(Object.keys(data));
// 利用Object.keys方法取出data的key值
Object.keys(data).forEach(key => {
// 定义响应方法 即劫持数据的getter和setter方法
this.defineReactive(data, key, data[key]);
})
}
}
利用Object.defineProperty方法重新定义data中各个数据的get和set方法。
/**
*
* @param {object} data vue实例中的data数据
* @param {string} key 遍历到的key值
* @param {string} value key值对应的value
*/
defineReactive(data, key, value) {
const self = this;
// 递归遍历 直到value不再为object
self.observer(value);
// 劫持并监听所有属性 利用Object.defineProperty重新定义get和set方法
Object.defineProperty(data, key, {
enumerable: true,
configurable: false,
get() {
return value;
},
set(newVal) {
// 注意在修改对象值时,要对新值添加监听
self.observer(newVal)
if (value !== newVal) {
console.log("监听到数据变化:" + key + " 由 " + value + " 变成 " + newVal);
value = newVal;
}
}
})
}
至此,完成了对数据的劫持监听,在console修改data中的数据时,可以看到监听输出。
vm.$data.htmlStr="33333" Observer.js:7
33333 Observer.js:39
监听到数据变化:htmlStr 由 <h4>还喜欢和大家一起学习。</h4> 变成 33333
接下来将实现Vue中的wathcer,从而实现视图驱动数据变化。
demo地址:Demo