数组如何进行劫持和观测
对数组[{a:1}]进行劫持
// value = [{a:1}]
observeArray(value){
for(let i = 0; i < value.length; i++){
// 将数组里的内容{a:1}丢给observe函数进行劫持
observer(value[i]) // 劫持之后,a有了get和set方法
}
}
对数组进行追加push后劫持
- 假如data里有个数组arr = [{a:1}],通过push追加上之后vm.data.arr.push({b:2})
新追加的b没有被劫持。 - 如何让新追加的数组也被劫持?(需要继承改造Array方法)
// 判断三种追加方式 push,unshift,splice
let inserted
switch(item){
case 'push':
case 'unshift':
inserted = args
break;
case 'splice':
inserted = args.splice(2)
break;
}
// 获取__ob__属性
let ob = this.__ob__
// 判断有没有值
if(inserted){
ob.observeArray(inserted) // 对我们添加的对象进行劫持
}
return result
//获取data时,给data每个值定义一个属性
Object.defineProperty(data,'__ob__',{
enumerable:false, // 不可枚举
value:this // 指向当前实例
})
- observeArray 方法
obserArray(value) {
//进行循环
value.forEach(item => {
Observer(item)
})
}
- Observer方法
export function Observer(data) {
// data 我们需要进行判断 typeof object null
//不能不是对象 并且不是null
if (typeof data !== 'object' || data == null) {
return;
}
//判断用户是否已经观测
if(data.__ob__){
return data;
}
//对这个是数据进行劫持 我们通过一个类
return new observe(data)
}
- 完整的observe类
class observe {
constructor(value) {
//1 给所有的对象类型添加一个dep 属性
this.dep = new Dep() // 注意 (1){} (2) [] 不是给里面属性添加dep
// console.log(data)
//使用defineProperty 重新定义属性 作用用来观测数据已经劫持过来
//判断一个对象是否被观察过看他有没有 __ob__这个属性
console.log(value);
Object.defineProperty(value,"__ob__",{
enumerable:false, //不能枚举
configurable:false,
value:this
})
if (Array.isArray(value)) { //注意对数组中的数据进行劫持 方法 劫持 修改数据的方法
//我希望调用push shift unshift splice sort reverse pop 这七个方法,那么我们就可以对
//你这个方法进行劫持
// 函数劫持,切片编程 []._
value.__proto__ = arrayMethods // 对象__proto__属性:
//监听数组中的值时对象
this.obserArray(value)
} else {
this.walk(value)
}
}
obserArray(value) {
//进行循环
value.forEach(item => {
Observer(item)
})
}
walk(data) { //数据是对象的的{a:{b:{}}}
//循环
let keys = Object.keys(data) //获取对象的key 注意这个key 只是 对象的最外层的
keys.forEach(item => {
defineReactive(data, item, data[item]) //Vue.util 中有的
})
}
}
网友评论