关于 Vue 3 的 ref,这些细节你了解了多少?

ref 自动解包 - 不易发现的小秘密

在模板上下文中,只有顶级才能被解包

在下面代码,sex和info是顶级属性,但info.value.age却不是

csharp 复制代码
--视图部分
{{ info.age + 1 }}
{{ '性别:' + sex }}
--js部分
const sex = ref('男')
const info = {
  age: ref(18)
}

按照上面代码执行,第一行代码执行结果是[object object]1,因为info.age 还是一个ref对象没有被解包。只有把它解构出来变成顶级属性,结果才能变成预期中的19

js 复制代码
const {age} = info

还需要注意的一点是:如果ref是文本插值中的最终展示的值,它也可以被解构,这是文本插值中的一个便利的地方

复制代码
{{info.age}}

浅层ref与常规ref的区别

1、浅层ref仅响应顶层属性变化换句话说就是只有把.value整体换掉才会触发更新;常规ref则是整体换掉或修改其内部属性值都会触发更新。

js 复制代码
// 创建浅层 ref
const state = shallowRef({ 
  count: 0,
  nested: { value: 1 }
})

// 会触发响应式更新(替换整个值)
state.value = { count: 10 }

// 不会触发更新(修改嵌套属性)
state.value.count = 20       // 无反应
state.value.nested.value++   // 无反应

2、浅层ref可以减少大型数据的响应性开销,从而达到优化性能的效果,但需要注意:改变其浅层ref变量的属性,不会让视图更新h; 如果遇到特殊情况可使用以下方式强制更新。

js 复制代码
import { triggerRef } from 'vue'

// 修改内部属性后强制更新
state.value.nested.value = 30
triggerRef(state) // 手动触发更新

为什么使用.value的ref

首先我们需要简单了解一下vue的响应式系统它是怎么样的工作的。

当使用一个ref变量,且在过程中对变量进行了访问和修改,vue会监听变量的变化,然后让对应的DOM进行响应更新。

在标准JavaScript中,监听普通变量访问和修改是行不通的,但可通过getter和setter方法来拦截对象get、set的操作,而.value给了vue检测的机会

js 复制代码
// 伪代码,不是真正的实现
const myRef = {
  _value: 0,
  get value() {
    track()
    return this._value
  },
  set value(newValue) {
    this._value = newValue
    trigger()
  }
}

ref与reactive的pk - 谁会更胜一筹

我们会从reactive()的局限性作为一个切入点,进行讨论。

1、reactive只能使对象类型的数据具有响应式,但ref可以让对象类型(如:对象、数组等)和原始类型(如:string、number等)的数据都具有响应式。

2、reactive 不能替换整体对象,因为vue的响应式是追踪属性实现的;但ref是通过.value调用的,所以可以替换整个对象。

3、reactive 对解构不友好,当我们将响应式对象解构为一个变量或者将该属性值传给函数,就会丢失响应式链接

scss 复制代码
const state = reactive({ count: 0 })

// 当解构时,count 已经与 state.count 断开连接
let { count } = state
// 不会影响原始的 state
count++

// 该函数接收到的是一个普通的数字
// 并且无法追踪 state.count 的变化
// 我们必须传入整个对象以保持响应性
callSomeFunction(state.count)

基于以上几点,建议使用ref作为声明响应式变量的主要API

彩蛋

我在寻找志同道合的同学,互相监督坚持每日打卡学习,学习路线如下:cssvueJavaScriptnode如何使用AI来提升编程能力 ,如果你有兴趣可以私信我或直接联系我 wx:wx_zysu

相关推荐
百花~2 分钟前
前端三剑客之一 HTML~
前端·html
lang2015092834 分钟前
Spring远程调用与Web服务全解析
java·前端·spring
Sheldon一蓑烟雨任平生1 小时前
Vue3 依赖注入(provide 和 inject)
vue.js·inject·provide·vue3 依赖注入·跨级别组件通信
listhi5203 小时前
利用React Hooks简化状态管理
前端·javascript·react.js
paopaokaka_luck3 小时前
基于SpringBoot+Vue的助农扶贫平台(AI问答、WebSocket实时聊天、快递物流API、协同过滤算法、Echarts图形化分析、分享链接到微博)
java·vue.js·spring boot·后端·websocket·spring
一点一木3 小时前
🚀 2025 年 10 月 GitHub 十大热门项目排行榜 🔥
前端·人工智能·github
华仔啊3 小时前
这个Vue3旋转菜单组件让项目颜值提升200%!支持多种主题,拿来即用
前端·javascript·css
非凡ghost3 小时前
Adobe Lightroom安卓版(手机调色软件)绿色版
前端·windows·adobe·智能手机·软件需求
Sheldon一蓑烟雨任平生4 小时前
Vue3 重构待办事项(主要练习组件化)
vue.js·重构·vue3·组件化练习
BestAns4 小时前
Postman 平替?这款轻量接口测试工具,本地运行 + 批量回归超实用!
前端