# vue3 vs vue2
## 响应式
v3 采用Proxy代理
Proxy是啥
对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
语法 const p=new Proxy(obj,handler)
接受两个参数 1.obj是要进行包装的对象,可以是数组,函数,对象,另一个代理
2.handler 是执行对p操作的行为,是一个一函数做属性的对象
const handler={
get:(obj,prop)=>{
return prop in obj?obj[prop]:11
}
}
const p = new Proxy({},handler)
p.s = "cao"
p.c = undefined
console.log(p.s , p.c)//cao,undefined
console.log('c' in p, p.c); // false, 11
### ref/reactive原吗
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
track(target, key)
return target[key]
},
set(target, key, value) {
target[key] = value
trigger(target, key)
}
})
}
function ref(value) {
const refObject = {
get value() {
track(refObject, 'value')
return value
},
set value(newValue) {
value = newValue
trigger(refObject, 'value')
}
}
return refObject
}
// 这会在一个effect(副作用)就要运行之前被设置
// 我们会在后面处理它
let activeEffect
function track(target, key) {
if (activeEffect) {
const effects = getSubscribersForProperty(target, key)
effects.add(activeEffect)
}
}
function trigger(target, key) {
const effects = getSubscribersForProperty(target, key)
effects.forEach((effect) => effect())
}
### 那这个effect又是啥啊?
我来解释他,再js里面
let A0 = 1
let A1 = 2
let A2 = A0 + A1
console.log(A2) // 3
A0 = 2
console.log(A2) // 仍然是 3
A0变了A2是不会自动更新的,那想要自动更新,我们就得写个方法
let A2
function update() {
A2 = A0 + A1
}
这个update()函数会产生一个effect(副作用),或者就简称为影响,因为它会更改程序里的状态。
A0 和 A1 被视为这个影响的依赖,因为它们的值被用来执行effect(影响)。因此这个effect(影响),也可以说是一个它依赖的订阅者。
### effect知道了是updata函数产生的影响,那再js里面A0变化了怎末去调用updata()呢?
还需要一个whenDepsChange(update),能够在 A0 或 A1 (这两个依赖)变化时调用update()(产生影响)。
我理解上跟vue3里的trigger这个差不多,就是当set劫持到变化的时候,就调用trigger()触发副作用,但是只是我理解,很大可能是错的
### 总结
#### 在 Vue 2 中使用Object.definePropert
把这些 property 全部转为getter/setter。Object.defineProperty只能实现对对象属性进行数据劫持,并且数据劫持式层层递归,消耗很大。对于对象的属性、方法,新增、删除则无能为力。另外,对数组数据存在缺陷
const obj = {name: "vue", arr: [1, 2, 3]};
Object.keys(obj).forEach((key) => {
let value = obj[key];
Object.defineProperty(obj, key, {
get() {
console.log(`get key is ${key}`);
return value;
},
set(newVal) {
console.log(`set key is ${key}, newVal is ${newVal}`);
value = newVal;
}
});
});
#### 在 Vue 3 中使用Proxy来创建响应式对象
将getter/setter用于ref。Proxy可以实现对整个对象的劫持,降低消耗,提高性能。能完美各类数据(包括,对象、数组、以及代理)。
const obj = {name: "vue", arr: [1, 2, 3]};
function proxy