vue 同通过Object.defineProperty( )数据劫持方法里的get,set属性来监听data里的数据变化
一,先熟悉下Object.defineProperty( )及其属性get,set
通过以下代码就能理解
var Book = {}
var name = '';
Object.defineProperty(Book, 'name', {
set: function (value) {
name = value;
console.log('你取了一个书名叫做' + value);
},
get: function () {
return '《' + name + '》'
}
})
Book.name = 'vue权威指南'; // 你取了一个书名叫做vue权威指南
console.log(Book.name); // 《vue权威指南》
Book.name是在设置值时触发set方法
console.log(Book.name)是在获取值时触发get方法
二,1.实现一个Observer
Observer是一个数据监听器,其实现核心方法就是前文所说的Object.defineProperty( )。如果要对所有属性都进行监听的话,那么可以通过递归方法遍历所有属性值,并对其进行Object.defineProperty( )处理。如下代码,实现了一个Observer。
function defineReactive(data, key, val) {
observe(val); // 递归遍历所有子属性
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function() {
return val;
},
set: function(newVal) {
val = newVal;
console.log('属性' + key + '已经被监听了,现在值为:“' + newVal.toString() + '”');
}
});
}
function observe(data) {
if (!data || typeof data !== 'object') {
return;
}
Object.keys(data).forEach(function(key) {
defineReactive(data, key, data[key]);
});
};
var library = {
book1: {
name: ''
},
book2: ''
};
observe(library);
library.book1.name = 'vue权威指南'; // 属性name已经被监听了,现在值为:“vue权威指南”
library.book2 = '没有此书籍'; // 属性book2已经被监听了,现在值为:“没有此书籍”
这是vue.2.0对对象的变化侦测实现的基础原理,接下来是考虑把它做成一个class类,然后添加保存依赖以及触发依赖; 数组又是不同的侦测方法,主要是通过数组的方法(push,unshift等)添加拦截器。
所以 对象的侦测缺点:在添加删除时无法侦测到,也就不能实时更新渲染;
数组缺点是:arr.[0] arr.length=0 无法侦测
vue提供了set,delete方法
推荐一本书里面有详细介绍《深入浅出VUE.js》