vue设计与实现 第6章 ref 响应原理 笔记

ref 函数实现代码

const a = ref(1);
function ref(value){
    const wrapper = {value}
    Object.defineProperty(wrapper,'__v_isRef',{
        value: true
    })
    return reactive(wrapper)
}

  把新建一个对象,value 属性是原始值,再把对象交给 reactive 进行响应式处理。所以要获取 ref 的值要拿取其 value 属性。 这里还添加了 不可遍历、配置、改写的属性 __v_isRef。标识 ref 类型。

ref 还能够用于响应式丢失问题

解构和展开运算符 会让响应式数据失去响应 下面是例子

复制代码
const obj = reactive({ foo: 1, bar: 2 });
let { foo, bar } = obj;
const target = {
    ...obj,
};
foo = 123;
target.foo = 2;
console.log(obj);

const a = ref(1);
let { value } = a;
value = 456;
console.log(a);
复制代码

 

 

   打印结果可以看出,解构和展开的属性已经没了和原来的响应式数据的联系,如何继续保持这种联系呢? 可用 toRef 和 toRefs API 

toRef 代码实现

 

复制代码
function toRef(target,key){
    const wrapper = {
        get value(){
            return Reflect.get(target,key)
        },
        set value(newvalue){
            return Reflect.set(target,key,newvalue)
        }
    }
    Object.defineProperty(wrapper,'__v_isRef',{
        value: true
    })
    return wrapper
}
复制代码

 

  toRef 就是把对象的某个属性转为 ref 。实现和 ref 函数差不多,只不过 ref 是把新建的对象 交给 reactive 。

  而 toRef 是改写新建的对象的 value 属性的 get 方法和 set 方法,关联上目标对象属性。

 

toRefs 代码实现

 

function toRefs(target){
    const wrapper = {}
    for (let key in target) {
        wrapper[key] = toRef(target,key);
    }return wrapper
}

 

  toRefs 只是循环目标对象属性,调用 toRef 

 

现在又有了新的问题,虽然把响应式丢失解决了,但是必须通过 value属性 才能访问,例子

const obj = reactive({ foo: 1, bar: 2 });
const target = {...toRefs(obj)};
target.foo.value

解决方案,创建一个代理对象,每次取值时是 ref 类型,返回 value 属性

复制代码
function proxyRefs(target){
    return new Proxy(target,{
        get (target,key,receiver) {
            const res = Reflect.get(target,key,receiver);
            return res.__v_isRef ? res.value:res
        },
        set (target,key,newVal,receiver){
            if(target[key].__v_isRef) {
                Reflect.set(target[key],value,newVal,receiver)
                return true
            }
            return Reflect.set(target,key,newVal,receiver)
        }
    })
}
复制代码

 

 

 

   在vue 组件中,模板能不用 value 取到值,那是因为 setup 函数返回的数据会传递给 proxyRefs 函数进行处理。

reactive 也有自动调用 proxyRefs ,例子

const count = ref(1);
const obj = reactive(count);
obj.count // 1

 

posted @   。吃什么  阅读(312)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示