Vue3:详解toRef
toRef的核心作用是什么
toRef本质上是创建了一个 Ref 对象 ,因为从reactive对象中提取出来的属性,会流失响应性,toRef就是为了解决这个问题,它提取单个属性并保持响应式连接。
基本用法
import { reactive, toRef } from 'vue'const state = reactive({name: '张三',age: 25
})// 创建对 name 属性的 ref 引用
const nameRef = toRef(state, 'name')
关键特性:双向同步
// 修改源对象,ref 同步更新
state.name = '李四'
console.log(nameRef.value) // '李四'// 修改 ref,源对象也同步更新
nameRef.value = '王五'
console.log(state.name) // '王五'
解决的核心问题
直接解构会丢失响应式:
const state = reactive({ name: '张三' })// ❌ 错误做法
const { name } = state
state.name = '李四' // name 不会更新!// ✅ 正确做法
const nameRef = toRef(state, 'name')
state.name = '李四' // nameRef.value 同步更新
实际应用场景
1. 组件间传递单个属性
// 父组件
const state = reactive({ name: '张三', age: 25 })// 只传递 name,但保持响应式
<ChildComponent :name="toRef(state, 'name')" />
2. 组合式函数中精确暴露
function useForm() {const form = reactive({username: '',password: '', remember: false})// 只暴露需要单独控制的字段return {usernameRef: toRef(form, 'username'),passwordRef: toRef(form, 'password')}
}// 使用时
const { usernameRef, passwordRef } = useForm()
3. 处理可选属性
const state = reactive({ name: '张三' })// 为可能不存在的属性设置默认值
const scoreRef = toRef(state, 'score', 100)
console.log(scoreRef.value) // 100
注意事项
- 源对象必须是 reactive 创建的,普通对象无效
与 ref 的区别
const state = reactive({ count: 0 })// toRef: 保持连接
const countRef1 = toRef(state, 'count')
countRef1.value++ // state.count 也变成 1// ref: 独立副本
const countRef2 = ref(state.count)
countRef2.value++ // state.count 还是 0
总结
toRef 是响应式对象属性的“精准提取器”,确保提取出来的属性仍然保持响应式连接,特别适用于需要单独管理或传递某个属性的场景。
