Vue3 开发避坑指南:ref 和 reactive 的关键不同

333 阅读4分钟

大家好,最近又重新出发面试了,一个不小心触碰到盲点了。被问到ref和reactive的区别,感觉自己答的比较简单,回来总结总结

image.png

vue3中的响应式api

响应式工具
ref(深层响应式追踪)创建响应式引用对象,可包装任何类型的值。访问值时需用 .value 属性
reactive(深层响应式追踪)响应式对象或数组,对其所有属性进行深层响应式追踪
shallowRef(追踪引用本身)响应式引用对象,仅对引用本身进行响应式追踪,内部属性变化不触发更新
customRef(根据实现逻辑)自定义 ref,可自定义 ref 的 get 和 set 操作,实现特殊响应式逻辑

ref 和 reactive

这两个工具可以让数据变得响应式,但是在使用的场景,优缺点等方面存在很多的不同。

image.png

ref

创建一个包含响应式数据的引用,可以包裹任意类型的数据,无论是基本数据类型(如字符串、数字、布尔值)还是复杂的对象和数组。访问或修改 ref 所包含的数据,Vue 能够自动追踪这些操作并在数据变化时更新与之绑定的视图

ref
优点(1)ref 的使用非常直观,创建和访问都很方便。 / (2)可以包裹任何类型的数据,通过 .value 明确区分对响应式数据的操作。 / (3)在模板中使用时,无需额外的语法,Vue 自动解包
缺点(1)需要频繁使用 .value / (2)包裹深层嵌套的对象或数组时,虽然 Vue 能够处理响应式,但在性能上可能不如 reactive 直接创建的响应式对象和数组,因为它需要额外的解包操作
特殊情况(1)ref 嵌套在 reactive 中:Vue 会自动解包 ref,可以直接访问其值 (2)在组合式 API 中,ref 常用于定义响应式状态和计算属性

reactive

专门用于创建响应式的对象和数组。它会对传入的对象或数组进行深度转换,使其所有属性都具备响应式。

reactive
优点(1)直接对对象和数组进行操作,无需额外的 .value 语法 / (2)处理大型的、复杂的对象和数组时,性能表现更好,因为减少了不必要的中间层操作 / (3)包含多个相关属性的复杂状态,代码结构更清晰
缺点(1)只能用于创建对象和数组的响应式,对于基本数据类型,需要先将其包装成对象,使用起来不如 ref 直接 / (2)直接解构 reactive 对象会导致失去响应式
特殊情况(1)直接解构 reactive 对象会失去响应式,常在表单定义的时候可能会用到,需要注意。/ (2)当将 reactive 对象作为函数参数传递时,要注意函数内部对对象的修改是否会影响到原始对象。

shallowRef 和 customRef

这两个api在我的开发使用过程中是使用的比较少的,但是存在就有它的意义。说不定未来就会使用到,或者说了解了后,后续需要用到也能有印象

shallowRef

对于 shallowRef 它的特点是:仅对引用本身进行响应式追踪,内部属性变化不触发更新

区别
引用本身例如:对象和数组是引用类型。当你创建一个对象或数组时,变量存储的并非对象或数组的实际内容,而是指向内存中该对象或数组的引用shallowRef 对这个引用进行响应式追踪,也就是当这个变量指向的内存地址发生改变时,Vue 会检测到这种变化并触发更新
内部更新引用类型(对象或数组)内部属性或元素的变化,例如:修改对象的某个属性值,或者向数组中添加、删除元素等操作

根据这个特性,说明对于处理大型对象或数组,且只需要监听对象或数组引用的变化,不需要监听其内部属性变化时。此api可以减少响应式追踪的开销,提高性能

customRef

对于 customRef 它的特点是:简单来说就是自定义,对于自定义这个词就可以了解到它的可操作性是很高的,同时也代表着如果逻辑不正确问题也会比较多

区别
track()告诉 Vue 当前的读取操作产生了一个依赖关系,用于追踪依赖。 vue响应式系统中它帮助 Vue 建立了数据和依赖之间的联系
trigger()Vue 会通知所有依赖这个数据的地方进行更新,用于触发更新

简单的测试代码段

对于shallowRef的案例 : 定义了两个函数,去对shallowRef数据进行修改,查看修改后有什么不同。

对于customRef的案例 : 使用 customRef 创建了一个节流的 ref