聊聊业内争论不休的ref和reactive
聊聊业内争论不休的ref和reactive
YuXiang引言
ref
和 reactive
可以称做是 Vue 响应式 API 中的周瑜和诸葛亮。那么问题来了,你会怎么选?本来将讨论 ref 和 reactive 的区别,并说一下我个人对于这件事的看法。
一、ref 和 reactive 的基础概念
1. ref 是什么?
ref 是将基本类型数据(如字符串、数字、布尔值等)
转换为响应式对象。
- ref 主要用于创建单一的值,或者是一个不可变的引用。
- 它返回的是一个包含
value
属性的对象,value 里存放着你传给 ref 的值。
1 | import { ref } from "vue"; |
2. reactive 是什么?
reactive 是将对象和数组
转为响应式数据。可以直接操作对象或数组,而不需要使用 value,而且会自动追踪这些对象内部的变化。
- reactive 适用于复杂数据结构,比如对象和数组。
- 直接对对象的属性进行修改,它会自动变成响应式,视图也会随着变化而更新。
1 | import { reactive } from "vue"; |
二、ref 和 reactive 的区别
1. 数据类型支持不同
- ref 一般用于简单数据类型(比如数字、字符串、布尔值),也可以用于复杂数据类型(底层依然是使用reactive去实现)。
- reactive 仅用于对象、数组这类复杂数据类型。
2. 使用方式不同
- 使用 ref 时,数据存放在 value 中,所以需要通过 value 来访问或修改值。
- 使用 reactive 时,数据就是直接访问的,和普通的对象或数组一样,不需要 value。
3. 对象的响应式
- ref 只能对基本数据类型进行响应式处理,如果你需要对对象进行响应式处理,应该使用 reactive。
- 如果你把一个对象传给 ref,它会变成一个对象的引用,而不是直接响应式对象。
1 | const person = ref({ |
上面这段代码我们依然需要通过 value 来修改对象的属性,这是因为我们用 ref 包装了整个对象。
4. 性能差异
- reactive 会对对象进行深度代理,这意味着对象的所有嵌套属性都会变成响应式的。所以,如果对象的嵌套层级很深,可能会稍微影响性能。
- ref 则比较轻量,它只会对单个数据进行响应式处理。
三、什么时候使用 ref,什么时候使用 reactive?
- 使用 ref:
- 当你只有一个简单的原始值(如数字、字符串、布尔值等)时,使用 ref。
- 比如,计数器、切换状态这样的场景。
1 | const count = ref(0); |
- 使用 reactive:
- 当你需要操作对象或者数组时,使用 reactive。
- 比如,存储表单数据、用户信息等。
1 | const user = reactive({ |
四、ref 和 reactive 混用的场景
我们也可以把 ref 和 reactive 结合使用,用于处理复杂数据结构。例如,你有一个对象,它的某个属性是基本数据类型,你可以使用 ref 来包装这个基本数据类型,其他部分让 reactive 去处理。
1 | const state = reactive({ |
五、产生分歧的原因
每个人有自己的技术偏好,这很正常,不必要非得论个高低。 正如以前讨论 JavaScript 是否需要加分号一样,大家会有不同意见。
呼声较高的认为只用 ref 就可以,反正 Vue3 的相应式系统已经很强大了,搞那么麻烦干啥。反正能用reactive写的,ref也能搞定。
但也有一部分开发者觉得应该分开用,特别是当你需要引用复杂对象时,reactive表现得更好,因为它会把整个对象变成响应式,不用担心某个属性会错过被追踪的情况。而 ref 适合那种简单的、原始的类型,比如count、isActive,不容易搞错。
六、我的看法
产生这种分歧有其历史背景。尤大曾提到,reactive 主要是为了照顾 Vue 2 用户的使用习惯,毕竟在 Vue 2 中,大家习惯性地使用 this.xxx 进行数据访问和操作。而 reactive 的体验会更接近 Vue 2,允许你把各种东西都放进去,这也间接表明了,暴露 reactive 这个 API 其实并非必需的。
个人来说,我更倾向于尤大所说的全程使用 ref。混合使用 reactive 和 ref 确实会出现一些问题,尤其是有些开发者会把所有东西都丢到 reactive 里,久而久之会增加重构的难度。相比之下,ref 的使用则更加灵活,且两个 ref 声明之间没有强绑定的关系,使得重构和维护更加方便。
另外,从团队协作的角度来看,协同性也非常重要。大家如果遵循一套统一的开发规则,也能够大大减少冲突和混乱。