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

相关推荐
weixin199701080166 小时前
【性能提升300%】仿1688首页的Webpack优化全记录
前端·webpack·node.js
冰暮流星6 小时前
javascript之数组
java·前端·javascript
晚霞的不甘7 小时前
Flutter for OpenHarmony天气卡片应用:用枚举与动画打造沉浸式多城市天气浏览体验
前端·flutter·云原生·前端框架
weixin79893765432...7 小时前
Vue 渲染体系“三件套”(template 模板语法、h 函数和 JSX 语法)
vue.js·h函数·template 模板·jsx 语法
xkxnq7 小时前
第五阶段:Vue3核心深度深挖(第74天)(Vue3计算属性进阶)
前端·javascript·vue.js
三小河7 小时前
Agent Skill与Rules的区别——以Cursor为例
前端·javascript·后端
Hilaku7 小时前
不要在简历上写精通 Vue3?来自面试官的真实劝退
前端·javascript·vue.js
三小河7 小时前
前端视角详解 Agent Skill
前端·javascript·后端
Aniugel7 小时前
单点登录(SSO)系统
前端
鹏多多8 小时前
移动端H5项目,还需要react-fastclick解决300ms点击延迟吗?
前端·javascript·react.js