关于 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

相关推荐
超人不会飛13 分钟前
就着HTTP聊聊SSE的前世今生
前端·javascript·http
蓝胖子的多啦A梦17 分钟前
Vue+element 日期时间组件选择器精确到分钟,禁止选秒的配置
前端·javascript·vue.js·elementui·时间选选择器·样式修改
夏天想19 分钟前
vue2+elementui使用compressorjs压缩上传的图片
前端·javascript·elementui
海天胜景23 分钟前
vue3 el-table 列增加 自定义排序逻辑
javascript·vue.js·elementui
今晚打老虎z27 分钟前
dotnet-env: .NET 开发者的环境变量加载工具
前端·chrome·.net
用户38022585982433 分钟前
vue3源码解析:diff算法之patchChildren函数分析
前端·vue.js
烛阴38 分钟前
XPath 进阶:掌握高级选择器与路径表达式
前端·javascript
小鱼小鱼干42 分钟前
【JS/Vue3】关于Vue引用透传
前端
JavaDog程序狗44 分钟前
【前端】HTML+JS 实现超燃小球分裂全过程
前端
独立开阀者_FwtCoder1 小时前
URL地址末尾加不加 "/" 有什么区别
前端·javascript·github