news 2026/9/12 19:40:13

Vue3 零基础每日笔记(012):toRef 与 toRefs——解构丢响应式的终极解药

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3 零基础每日笔记(012):toRef 与 toRefs——解构丢响应式的终极解药

一、前言

005 篇埋过一个伏笔:“解构丢失响应式,要用 toRefs,那是 012 篇的主角”。今天它来了。这是响应式基础篇的收官前最后一课:搞懂它,前面所有"丢响应式"的坑一次性填平,也为第五阶段的组合式函数铺好路。

三秒回顾问题:解构 = 断链

constuser=reactive({name:'小明',age:18})const{name}=user// ❌ 拿到的是死值 '小明'name='小红'// 页面纹丝不动,Vue 也不认识这个变量了

解构的一瞬间,值被"复印"了一份出来,和原对象的响应式链接当场断裂。toRef 系列的作用就一句话:解构,但不断链

二、toRef:给单个属性"办一张连卡"

toRef(对象, '属性名')为对象的某个属性创建一个保持链接的 ref:

<template> <p>{{ name }}</p> <button @click="name = '小红'">改名</button> </template> <script setup> import { reactive, toRef } from 'vue' const user = reactive({ name: '小明', age: 18 }) // name 和 user.name 是同一个东西的两扇门 const name = toRef(user, 'name') // 改 name.value,user.name 跟着变,页面也更新 name.value = '小红' console.log(user.name) // '小红' </script>

双向互通:改name.valueuser.name变;改user.namename.value也变。不是复印,是同一条线的两个插头。

三、toRefs:全部属性一起"办卡"

toRefs(对象)把对象第一层的每个属性都转成 toRef,返回一个普通对象。它就是为解构而生的:

<template> <p>{{ name }}:{{ age }} 岁</p> <button @click="age++">过生日</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}from'vue'exportfunctionuseUser(){conststate=reactive({name:'小明',age:18})functiongrow(){state.age++}// ❌ return state → 调用方一解构就断// ✅ return toRefs(state) → 怎么解构都是活的return{...toRefs(state),grow}}
<template> <p>{{ name }}:{{ age }} 岁</p> <button @click="grow">长一岁</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 解构后页面同步更新的演示】

六、踩坑记录

  1. toRefs 只转第一层:嵌套对象内部还是 reactive,toRefs(user).info.value.city用起来别扭,深层就直接user.info.city访问
  2. toRef 一个不存在的属性也合法toRef(user, 'hobby')创建后hobby.value = '篮球'会写回 user,适合属性动态添加的场景
  3. toRefs 后忘了 .value:script 里age++无效,要age.value++;模板里才自动解包
  4. 不要对 ref 用 toRefs:toRefs 是给 reactive 对象用的,ref 请直接用,别套娃
  5. 解构 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,面试高频题一次讲透。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 19:38:17

STM32H7R接OV5640:DCMIPP摄像头接口配置与调试指南

简介&#xff1a;面向STM32H7R系列嵌入式开发者的OV5640摄像头驱动资源&#xff0c;基于DCMIPP图像接口实现图像采集&#xff0c;适合机器视觉、工业检测等场景。包内代码基于HAL库&#xff0c;提供可直接编译运行的完整工程&#xff0c;开发者无需另起炉灶即可快速移植验证&am…

作者头像 李华
网站建设 2026/9/12 19:37:57

ECS自建MySQL vs 阿里云RDS:数据库托管选型的TCO深度对比

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 19:37:50

电子元器件检测:YOLO重构与大模型协同的工业视觉实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 19:36:45

国产操作系统学习指南:从内核到实战应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 19:35:36

Matlab实现自动泊车路径规划算法解析

1. 项目概述&#xff1a;自动泊车路径规划的核心价值停车难一直是城市驾驶者的痛点&#xff0c;特别是在拥挤的商业区或老旧小区。传统泊车需要驾驶员反复调整方向盘&#xff0c;不仅耗时耗力&#xff0c;还容易发生剐蹭。自动泊车系统通过传感器感知环境&#xff0c;由算法计算…

作者头像 李华
网站建设 2026/9/12 19:34:15

基于SmartMediaKit与YOLO的实时视频AI管线构建实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华