Vue响应式源码分析理解
响应式数据的核心就是数据变化了我们能知道,对象在vue2中采用了defineProperty 将数据定义成了响应式 (拦截所有的属性增加了getter 和setter 方法)
缺陷: 就是需要递归构建,不存在的属性无法被监听到,
vue3采用了的是proxy 直接可以对对象拦截,不用进行重写get set 方法,性能高 不需要直接递归 ,vue2中对数组并没有采用defineProperty 因为数组中可能数组很长 但是用户不会操作索引更改数据
- vue2中尽量减少层级数据的嵌套
- 如果不需要响应式的数据 就不要放在data中 ,合理使用Object.freeze()
- 尽量缓存使用过的变量
注:在vue2中 data中的数据 defineProperty 通过递归的方式进行给每个变量增加了getter setter 福冈发 来提供给后续继续使用的
那怎么将不是响应式的数据变成响应式? - 1、可以使用vue的$set() 方法
- 2、使用手写一个利用defineProperty来给数据增加get set方法
export function defineReactive(target,key,value){
//注:这个是闭包当前这个作用域不会被销毁
let chilOb = observe(value)// 这个value 如果是个对象的话 需要再次进行监听对象套对象\
// chilOb 拿到的是 Observe 实例
let dep = new Dep() //因为这是个闭包 所以相当与每个属性上都有一个dep 实例
Object.defineProperty(target,key,{
get(){
if(Dep.target){
dep.depend();
if(chilOb){
chilOb.dep.depend() //让数组跟对象本手进行依赖收集
if(Array.isArray(value)){
// 如果是数组套数组的化 需要递归重更新做依赖收集
dependArray(value)
}
}
}
return value
},
set(newValue){
if(newValue == value){return};
//传入的修改的如果是对象的话要对属性再次监听
observe(value);
value = newValue;
dep.notify(); //属性变化 就通知dep中对应所有的watcher 去进行更新视图
}
})
}