toRef
和 toRefs
都是 Vue 3 的 Composition API 中用于处理响应式引用的工具函数,但它们有不同的用途和行为。
toRef
作用:为响应式对象的某个属性创建一个 ref 引用,保持对该属性的响应式连接。
使用场景:
-
当你需要从响应式对象中提取单个属性并保持其响应性时
-
当你想要保持与源对象的属性同步时
示例
import { reactive, toRef } from 'vue'
const state = reactive({
count: 0,
name: 'Vue'
})
// 创建一个 ref,连接到 state.count
const countRef = toRef(state, 'count')
// 修改 ref 会更新原始对象
countRef.value++
console.log(state.count) // 1
// 修改原始对象也会更新 ref
state.count = 2
console.log(countRef.value) // 2
toRefs
toRefs
作用:将响应式对象转换为普通对象,其中每个属性都是指向原始对象相应属性的 ref。
使用场景:
-
在组合式函数中返回响应式对象时,保持解构后的响应性
-
当需要将响应式对象的属性作为独立的 ref 传递时
-
在模板中使用解构语法但仍需要保持响应性时
示例:
import { reactive, toRefs } from 'vue'
const state = reactive({
count: 0,
name: 'Vue'
})
// 将响应式对象转换为 refs 对象
const stateRefs = toRefs(state)
// 解构后仍保持响应性
const { count, name } = toRefs(state)
// 在组合式函数中的典型用法
function useFeature() {
const state = reactive({
x: 0,
y: 0
})
// 返回 toRefs 以便解构后仍保持响应性
return toRefs(state)
}
const { x, y } = useFeature()
主要区别
特性 | toRef | toRefs |
---|---|---|
输入 | 响应式对象 + 属性名 | 整个响应式对象 |
输出 | 单个 ref | 包含所有属性 ref 的普通对象 |
主要用途 | 提取单个属性保持响应性 | 解构整个对象同时保持响应性 |
同步性 | 与源属性保持同步 | 所有属性 ref 都与源对象保持同步 |
典型场景 | 需要单独处理某个属性时 | 组合式函数返回值或模板解构时 |
最佳实践
-
在组合式函数中返回响应式状态时,优先使用
toRefs
,这样使用者可以解构而不失去响应性 -
当只需要一个属性时,使用
toRef
更合适 -
对于可能不存在的属性,使用
toRef
更安全(它会为不存在的属性创建可写的 ref) -
在模板中使用解构时,先用
toRefs
处理响应式对象
// 组合式函数示例
function useUser() {
const state = reactive({
name: '',
age: 0,
isAdmin: false
})
// 获取数据逻辑...
return {
...toRefs(state),
// 其他非响应式值或方法
reset: () => { /*...*/ }
}
}
常见问题
-
toRef
和toRefs
的基本区别:-
toRef
:为响应式对象的单个属性创建 ref,保持与源属性的响应式连接 -
toRefs
:将响应式对象的所有属性都转换为 ref,返回一个普通对象,每个属性都是 ref
-
-
为什么需要这两个 API:
-
直接解构 reactive 对象会失去响应性,因为解构得到的是普通值
-
toRef/toRefs
可以保持解构后的响应性
-
-
toRef
和ref
的区别:-
ref
:创建一个全新的响应式引用,与原始值无关 -
toRef
:为已有响应式对象的属性创建引用,与源属性保持同步
-
-
toRef
的使用场景:-
当只需要对象中的单个属性时
-
当属性可能不存在时更安全
-
-
组合式函数中使用
toRefs
的原因:-
允许使用者解构返回的对象而不丢失响应性
-
保持组合式函数的灵活性
-
-
选择
toRef
的情况:-
当只需要单个属性时使用
toRef
更合适 -
性能考虑 - 避免不必要的转换
-
-
toRef
创建的 ref 和普通 ref 的区别:-
toRef
创建的 ref 不会触发视图更新当值变化时(因为它依赖于源 reactive 对象) -
普通
ref
创建的会触发更新
-
-
添加新属性后的情况:
-
不会自动变成 ref
-
toRefs
只在调用时转换当时存在的属性 -
补充:Vue 3 的响应式系统对动态添加的属性有局限
-
-
过度使用
toRefs
的性能问题及优化按需转换:只对用到的属性使用
toRef