reactive对比ref
- 从定义数据角度对比:
- ref用来定义:基本类型数据。
- reactive用来定义:对象(或数组)类型数据。
- 备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过
reactive
转为代理对象。
- 从原理角度对比:
- ref通过
Object.defineProperty()
的get
与set
来实现响应式(数据劫持)。 - reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。
- 从使用角度对比:
- ref定义的数据:操作数据需要
.value
,读取数据时模板中直接读取不需要.value
。 - reactive定义的数据:操作数据与读取数据:均不需要
.value
。
你可能有疑问,为什么对象类型不能用ref呢?
使用 ref 函数创建的响应式数据是基于 Vue 3 的 Ref 类型实现的,它主要用于包装基本类型的值,并提供了响应式的访问和更新接口。虽然 ref 可以用于创建对象类型的响应式数据,但并不建议这样做,因为在处理对象类型数据时,ref 的行为与预期可能不一致,而且在某些情况下会导致代码出现问题。
举个例子来说明为什么不建议使用 ref 来创建对象类型的响应式数据:
import { ref, reactive } from 'vue'; // 使用 ref 创建基本类型数据 const count = ref(0); // 使用 ref 创建对象类型数据 const user = ref({ name: 'Alice', age: 25 }); // 尝试修改对象属性 user.value.name = 'Bob'; console.log(user.value); // { name: 'Bob', age: 25 }
这个例子中,我们首先使用 ref 创建了一个基本类型的响应式数据 count,以及一个对象类型的响应式数据 user。然后,我们尝试直接修改 user 对象的属性,结果发现对象的属性修改成功了。
尽管我们使用了 ref 创建了 user 对象,但是 ref 返回的是一个 Ref 对象,而不是一个普通的对象。所以在修改 user 对象时,实际上是在修改 Ref 对象的 value 属性的值,而不是直接修改对象本身。但由于 Vue 3 对 Ref 对象进行了特殊处理,使其可以像普通对象一样使用,因此在这个例子中修改 user 对象的属性看起来是有效的。
然而,这种做法并不是 Vue 3 官方推荐的方式。为了避免出现意料之外的问题,并且保持代码的一致性和可读性,我们应该使用 reactive 函数来创建对象类型的响应式数据,而不是使用 ref哈