vue3响应式数据(ref,reactive)详解
ref
概念:
-
用于创建响应式的基本类型数据(如 string, number, boolean)
-
也可以用于对象和数组,但更推荐对基本类型使用
-
返回一个响应式的、可变的 ref 对象,该对象内部通过
.value
属性持有其值 -
模板中的 ref 属性(如
)会创建 DOM 元素的引用,这与响应式的 ref 是不同的概念import { ref } from \'vue\'const count = ref(0) // 创建console.log(count.value) // 访问count.value++ // 修改
特点:
-
在模板中使用时自动解包,无需
.value
-
在响应式对象中使用时自动解包
const state = reactive({ foo: 1, bar: 2})//直接使用即可,不需要state.foo.value++state.foo++console.log(state.foo)// 2
-
适合用于基本类型数据和需要在多处引用的响应式数据
reactive
概念:
-
用于创建响应式的对象(包括数组)
-
返回对象的响应式代理
-
只能用于对象类型(Object, Array, Map, Set 等)
import { reactive } from \'vue\'const state = reactive({ count: 0, name: \'Vue\'}) // 创建console.log(state.count) // 访问state.count++ // 修改
特点:
-
直接访问和修改属性,不需要
.value
-
解构或属性赋值会失去响应性
-
适合用于复杂对象和局部状态
toRef 和 toRefs
toRef
和toRefs
是 Vue3 组合式 API 中用于处理响应式引用的两个实用函数,它们可以帮助我们在解构或传递响应式对象时保持其响应性。toRef
toRef
用于为响应式对象上的某个属性创建一个 ref 引用,这个 ref 会与源属性保持同步。import { reactive, toRef } from \'vue\'const state = reactive({ foo: 1, bar: 2})// 创建一个与 state.foo 保持同步的 refconst fooRef = toRef(state, \'foo\')// 修改 ref 会更新原始属性fooRef.value++console.log(state.foo) // 2// 修改原始属性也会更新 refstate.foo++console.log(fooRef.value) // 3
toRefs
toRefs
将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向原始对象相应属性的 ref。简单理解,如图所示:
import { reactive, toRefs } from \'vue\'const state = reactive({ foo: 1, bar: 2})const stateRefs = toRefs(state)// ref 和原始属性保持同步stateRefs.foo.value++console.log(state.foo) // 2state.bar++console.log(stateRefs.bar.value) // 3
注意事项:
-
这两个函数只对响应式对象(reactive 创建)有效,对普通对象无效
-
使用解构赋值时,
toRefs
可以保持响应性,而直接解构会失去响应性 -
对于可能不存在的属性,可以使用
toRef
并提供默认值:const fooRef = toRef(state, \'nonExistent\', \'default value\')
实际应用:
-
基本类型优先使用
ref
-
复杂对象(层级较深)使用
reactive
-
组合式函数返回状态时优先返回
ref
,方便解构 -
使用
isRef
和isReactive
进行类型检查
-