Open rimochiko opened 4 years ago
Vue 2的做法
缺点:
Proxy:用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。 traps:提供属性访问的方法。这类似于操作系统中捕获器的概念。 Object|Array|Map|Set|WeakMap|WeakSet https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
let data = [1,2,3] let p = new Proxy(data, { get(target, key, receiver) { return target[key] }, set(target, key, value, receiver) { console.log(‘set value’) target[key] = value return true // 不加会报错,why? } }) p.push(4)
// get value: push // get value: length // set value: 3 1 // set value: length 4
p.push(1)
可以通过Reflect来返回 trap 相应的默认行为
解决 setTimeout 解决重复 trigger
set(target, key, value, receiver) { clearTimeout(timer) timer = setTimeout(() => { cb && cb() }, 0); return Reflect.set(target, key, value, receiver) }
p.bar.key = 2 // get value: bar
对于 receiver ,其实接收的是一个代理对象:// { a: {b: {c: 1 } } } 会返回内部a的对象;
解决: 递归代理
for (let key in data) { if (typeof data[key] === 'object') { res[key] = reactive(data[key], cb) } else { res[key] = data[key] } }
reactive.ts rawToReactive# 和 reactiveToRaw# 是两个弱引用的 Map# 结构,这两个 Map# 用来保存 原始数据# 和 可响应数据
判断 key 是否为 target 自身属性,以及设置val是否跟target[key]相等
Vue 2的做法
缺点:
Vue 3-Proxy API
Proxy:用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。 traps:提供属性访问的方法。这类似于操作系统中捕获器的概念。 Object|Array|Map|Set|WeakMap|WeakSet https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
直接用会有问题
多次调用
// get value: push // get value: length // set value: 3 1 // set value: length 4
p.push(1)
可以通过Reflect来返回 trap 相应的默认行为
解决 setTimeout 解决重复 trigger
trap只能代理一层
p.bar.key = 2 // get value: bar
对于 receiver ,其实接收的是一个代理对象:// { a: {b: {c: 1 } } } 会返回内部a的对象;
解决: 递归代理
reactive.ts rawToReactive# 和 reactiveToRaw# 是两个弱引用的 Map# 结构,这两个 Map# 用来保存 原始数据# 和 可响应数据
判断 key 是否为 target 自身属性,以及设置val是否跟target[key]相等