:toRef 与 toRefs——解构丢响应式的终极解药)
一、前言005 篇埋过一个伏笔“解构丢失响应式要用 toRefs那是 012 篇的主角”。今天它来了。这是响应式基础篇的收官前最后一课搞懂它前面所有丢响应式的坑一次性填平也为第五阶段的组合式函数铺好路。三秒回顾问题解构 断链constuserreactive({name:小明,age:18})const{name}user// ❌ 拿到的是死值 小明name小红// 页面纹丝不动Vue 也不认识这个变量了解构的一瞬间值被复印了一份出来和原对象的响应式链接当场断裂。toRef 系列的作用就一句话解构但不断链。二、toRef给单个属性办一张连卡toRef(对象, 属性名)为对象的某个属性创建一个保持链接的 reftemplate p{{ name }}/p button clickname 小红改名/button /template script setup import { reactive, toRef } from vue const user reactive({ name: 小明, age: 18 }) // name 和 user.name 是同一个东西的两扇门 const name toRef(user, name) // 改 name.valueuser.name 跟着变页面也更新 name.value 小红 console.log(user.name) // 小红 /script双向互通改name.value→user.name变改user.name→name.value也变。不是复印是同一条线的两个插头。三、toRefs全部属性一起办卡toRefs(对象)把对象第一层的每个属性都转成 toRef返回一个普通对象。它就是为解构而生的template p{{ name }}{{ age }} 岁/p button clickage过生日/button /template script setup import { reactive, toRefs } from vue const user reactive({ name: 小明, age: 18 }) // ✅ 先 toRefs 再解构每个变量都是活的 ref const { name, age } toRefs(user) /script解构出的 name、age 都是 ref改动会同步回 user页面照常更新。script 里记得 .value模板里不用——老规矩再次生效age.value// ✅ script 里// 模板里直接 {{ age }}四、黄金搭档reactive 的 state 转出去组合式函数第五阶段主角的标准套路内部用 reactive 聚合状态对外返回时 toRefs 打包调用方就能安心解构// useUser.js —— 一个迷你组合式函数import{reactive,toRefs}fromvueexportfunctionuseUser(){conststatereactive({name:小明,age:18})functiongrow(){state.age}// ❌ return state → 调用方一解构就断// ✅ return toRefs(state) → 怎么解构都是活的return{...toRefs(state),grow}}template p{{ name }}{{ age }} 岁/p button clickgrow长一岁/button /template script setup import { useUser } from ./useUser const { name, age, grow } useUser() // ✅ 解构响应式完好 /script记住这个形态第五阶段写 useMouse、useTitle 全是它。五、props 的解构同样的问题同样的解法props 也是响应式对象代理解构一样断链template p{{ msg }}/p /template script setup import { toRefs } from vue const props defineProps({ msg: String }) // ❌ const { msg } props → 父组件更新后页面不跟着变 // ✅ 正确姿势一不解构全程 props.xxx // ✅ 正确姿势二toRefs 再解构 const { msg } toRefs(props) /script面试和实战都常考props 为什么不能解构答props 是浅层响应式代理解构取出的是当时的死值断开了与父组件数据的链接需要解构时用 toRefs 保持链接。【截图位置父组件改数据子组件用 toRefs 解构后页面同步更新的演示】六、踩坑记录toRefs 只转第一层嵌套对象内部还是 reactivetoRefs(user).info.value.city用起来别扭深层就直接user.info.city访问toRef 一个不存在的属性也合法toRef(user, hobby)创建后hobby.value 篮球会写回 user适合属性动态添加的场景toRefs 后忘了 .valuescript 里age无效要age.value模板里才自动解包不要对 ref 用 toRefstoRefs 是给 reactive 对象用的ref 请直接用别套娃解构 computed 的返回值computed 返回的是 ref解构不丢响应式ref 本身就是盒子但const x computed(...).value就变死值了七、今日小结toRef / toRefs解构但不断链让解构出的每个变量保持与原对象的连接黄金搭档内部 reactive 聚合 return toRefs(state)对外暴露props 解构必须 toRefs或干脆全程 props.xxx这套姿势是组合式函数的地基第五阶段天天见作者陈志宝下篇预告响应式的面讲完了最后挖一次底Vue2 的 $set 为什么没了Vue3 改个新增属性为什么能自动更新下一篇响应式原理通俗版——Proxy vs Object.defineProperty面试高频题一次讲透。