ref 与 reactive 的区别笔记
一、概述
在 Vue 3 的组合式 API 中,ref 和 reactive 是两个非常重要的响应式工具,它们都用于创建响应式数据,但在使用方式、适用场景和内部实现上存在一些区别。
二、基本使用方式
1. ref
ref 用于创建一个响应式的引用对象,它可以接收任何类型的值,包括基本数据类型(如 number、string、boolean 等)和对象类型。通过 .value 属性来访问和修改其值。当传入对象时,ref 内部实际上会使用 reactive 对该对象进行处理以实现响应式。
{{ person.value.name }}
2. reactive
reactive 用于创建一个响应式的对象,它只能接收对象类型的值(包括普通对象、数组、Map、Set 等),并且不需要通过 .value 来访问和修改其属性。
{{ state.name }}
三、适用场景
1. ref
- 基本数据类型:当需要对基本数据类型(如数字、字符串、布尔值)进行响应式处理时,ref 是首选。因为基本数据类型没有属性,无法直接使用 reactive。
- 在模板中使用:在模板中使用 ref 时,Vue 会自动解包 .value,使得使用起来更加方便。
- 跨组件传递:ref 可以方便地在组件之间传递,接收方可以通过 .value 访问和修改其值。
- 复杂对象:虽然 ref 可用于复杂对象,但使用时要注意通过 .value 来操作对象。当传入对象时,ref 会借助 reactive 让对象具有响应式能力。
2. reactive
- 对象和数组:当需要对对象或数组进行响应式处理时,reactive 更加合适。它可以递归地将对象的所有属性转换为响应式的。
- 复杂数据结构:对于包含多个属性的复杂对象,使用 reactive 可以避免为每个属性创建单独的 ref,且使用时无需 .value 这样的额外操作。
四、内部实现区别
1. ref
ref 内部使用了一个 RefImpl 类来包装传入的值,通过 getter 和 setter 来实现响应式。当传入对象时,会调用 reactive 方法将对象转换为响应式对象。当访问 ref 的 .value 属性时,会触发 getter,收集依赖;当修改 .value 属性时,会触发 setter,通知依赖更新。
2. reactive
reactive 内部使用了 Proxy 对象来拦截对象的属性访问和修改操作。当访问或修改 reactive 对象的属性时,Proxy 会自动收集依赖或通知依赖更新。
五、注意事项
1. ref 在对象中的使用
当 ref 作为 reactive 对象的属性时,在访问时会自动解包 .value。
2. 响应式丢失问题
reactive 对象在解构赋值后会失去响应式特性,而 ref 不会。
综上所述,ref 和 reactive 各有优缺点,在实际开发中需要根据具体的场景选择合适的工具。