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
分类:
vue 设计与实现
标签:
vue.js
, vue.js 设计与实现
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)