Vue3 响应式基础 - reactive() 和 ref()
一、reactive()
reactive() 用于创建一个响应式的对象或数组(包括 Map、Set 这样的集合类型)。它返回一个代理对象,该对象的属性在被访问或修改时,能够触发相应的视图更新。
- 深层响应式:reactive() 创建的响应式对象是深层响应式的,即对象内部嵌套的属性也能被检测到变化。但需要注意的是,如果嵌套的对象是在响应式对象创建后添加的,那么这些新添加的对象不会自动变为响应式,除非使用 shallowReactive() 的方式显式声明。
- 限制:reactive() 仅对对象类型有效,且当响应式对象的属性被赋值或解构至本地变量,或传入一个函数时,会失去响应性。
- TypeScript 标注:可以通过在 reactive() 调用时传入一个类型参数来标注响应式对象的类型。
二、ref()
ref() 用于定义一个响应式变量,它可以接受任意类型的参数,并将其赋值给对象的 value 属性。ref() 返回的是一个响应式对象,该对象的 value 属性在被访问或修改时,能够触发相应的视图更新。
- 模板中解包:在模板中使用 ref() 定义的响应式变量时,Vue 会自动解包,即不需要加上 .value。但在非模板的 JavaScript 代码中,访问 ref() 返回的对象的值时需要加上 .value。
- 响应式对象中的解包:当 ref() 被嵌套在一个 reactive() 创建的响应式对象中时,会自动解包,即可以直接通过响应式对象访问 ref() 定义的变量的值,而不需要加上 .value。
- 数组和集合类型中不解包:与响应式对象不同,当 ref() 作为响应式数组或像 Map 这样的原生集合类型的元素被访问时,不会进行解包,需要加上 .value 来访问值。
- 获取 DOM 对象:在 Vue3 中,可以通过 ref() 获取 DOM 对象。在模板中,将 ref 属性绑定到 DOM 元素上,然后在 setup() 函数中通过 ref() 返回的响应式对象访问该 DOM 元素。需要注意的是,只有在组件挂载后才能访问到 DOM 元素,因此通常会在 onMounted() 生命周期钩子中执行相关操作。
总结:
- reactive() 适用于对象或数组的深层响应式需求,但需要注意嵌套对象的响应式处理以及属性赋值和解构时的响应性丢失问题。
- ref() 适用于任意类型的响应式变量定义,且在模板中会自动解包,方便使用。但在非模板代码中需要加上 .value 来访问值。
- 在使用 Vue3 的响应式系统时,应根据具体需求选择合适的 API,并遵循相应的使用规则和限制,以确保视图能够正确更新。