实现 proxyRefs
1. get
先看测试样例
it('proxyRef', () => {
const foo = {
bar: ref(1),
baz: 'baz',
}
// get
const proxyFoo = proxyRefs(foo)
expect(foo.bar.value).toBe(1)
expect(proxyFoo.bar).toBe(1)
})
这里我们看通过 proxyRefs 包装一个对象,那么该对象的属性如果存在 ref,那么就自动 unRef,既然是一个对象,我们就可以用到 proxy
export function proxyRefs(objectWithRefs) {
return new Proxy(objectWithRefs, {
get(target, key, receiver) {
// 自动 unRef
return unRef(Reflect.get(target, key, receiver))
},
})
}
2. set
proxyFoo.bar = 10
expect(proxyFoo.bar).toBe(10)
expect(foo.bar.value).toBe(10)
proxyFoo.bar = ref(20)
expect(proxyFoo.bar).toBe(20)
expect(foo.bar.value).toBe(20)
我们可以看到,set 是分为两种情况的,可能是一个 ref,也可能是一个原始值
export function proxyRefs(objectWithRefs) {
return new Proxy(objectWithRefs, {
get(target, key, receiver) {
// other code ...
},
set(target, key, value, receiver) {
// set 分为两种情况,如果原来的值是 ref,并且新的值不是 ref
// 那么就去更新原来的 ref.value = newValue
// 第二种情况就是原来的值是 ref,newValue 也是一个 ref
// 那么就直接替换就 OK 了
if (isRef(target[key]) && !isRef(value)) {
return (target[key].value = value)
} else {
return Reflect.set(target, key, value, receiver)
}
},
})
}
这样测试就可以跑通了
