大家好,最近又重新出发面试了,一个不小心触碰到盲点了。被问到ref和reactive的区别,感觉自己答的比较简单,回来总结总结
vue3中的响应式api
| 响应式工具 | |
|---|---|
| ref(深层响应式追踪) | 创建响应式引用对象,可包装任何类型的值。访问值时需用 .value 属性 |
| reactive(深层响应式追踪) | 响应式对象或数组,对其所有属性进行深层响应式追踪 |
| shallowRef(追踪引用本身) | 响应式引用对象,仅对引用本身进行响应式追踪,内部属性变化不触发更新 |
| customRef(根据实现逻辑) | 自定义 ref,可自定义 ref 的 get 和 set 操作,实现特殊响应式逻辑 |
ref 和 reactive
这两个工具可以让数据变得响应式,但是在使用的场景,优缺点等方面存在很多的不同。
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