我们使用vue3的时候就会发现script中的ref需要.value而template中的不用,其实他使用到到了proxyRefs对setup中的变量进行了转换,接下来就讲一讲proxyRefs原理及实现。
实现proxyRefs,主要就是对返回的proxy里面的get 和set进行处理
proxyRefs中get: 如果对象的属性为ref时返回.value,不然返回value proxyRefs中set: 对象属性的值为ref但是新赋的值又不为ref时候,需要为.value赋值,其他使用Reflect.set
知道了get set 要实现什么时候,那就很简单了
proxyRefs测试用例:
it('proxyRefs',()=>{
const user = {
age:ref(10),
name:"ljp"
}
//get
const proxyUser = proxyRefs(user)
expect(user.age.value).toBe(10)
expect(proxyUser.age).toBe(10)
expect(proxyUser.name).toBe('ljp')
//set
proxyUser.age = ref(10)
expect(proxyUser.age).toBe(10)
expect(user.age.value).toBe(10)
})
根据上面那个get set 分析,代码如下:
export function proxyRefs(objectWithRefs){
return new Proxy(objectWithRefs,{
get(target,key){
// 如果值为ref返回.value 不然返回value
return unRef(Reflect.get(target,key))
},
set(target,key,value){
// 之前的值为ref但是新赋的值又不为ref时候
if(isRef(target[key]) && !isRef(value)){
return target[key].value = value
} else {
return Reflect.set(target,key,value)
}
}
})
}