在 Vue 中,除了 reactive
、ref
和 toRefs
,还有多个一系列用于处理响应式数据的 API,它们各自针对特定场景,补充了响应式系统的能力:
1. toRef
:单个属性的响应式转换
将响应式对象的单个属性转换为独立的 ref
,且与原对象保持关联(修改 ref
会同步更新原对象)。
适用场景:需要单独传递对象的某个属性,同时保持其响应性。
import { reactive, toRef } from 'vue'
const user = reactive({
name: '张三',
age: 25
})
// 提取 user.age 为独立 ref
const ageRef = toRef(user, 'age')
ageRef.value++ // 修改后,原对象的 age 也会更新
console.log(user.age) // 26
2. shallowRef
:浅层响应式引用
仅对 .value
的直接赋值触发响应式更新,不监听内部属性变化(性能优化场景)。
适用场景:
- 存储大型数据(如复杂图表数据),无需深层响应式
- 避免不必要的嵌套属性监听,提升性能
import { shallowRef } from 'vue'
const data = shallowRef({ count: 0 })
// 直接修改 .value 会触发更新
data.value = { count: 1 } // 响应式生效
// 修改内部属性不会触发更新
data.value.count = 2 // 无响应式(视图不刷新)
3. shallowReactive
:浅层响应式对象
仅对对象的顶层属性做响应式处理,嵌套属性的变化不会触发更新。
适用场景:
- 处理层级极深的对象,但只关心顶层属性变化
- 优化性能(减少深层监听的开销)
import { shallowReactive } from 'vue'
const obj = shallowReactive({
a: 1,
nested: { b: 2 } // 嵌套对象无响应式
})
obj.a = 2 // 顶层属性变化,触发更新
obj.nested.b = 3 // 嵌套属性变化,无响应式
4. readonly
:只读响应式对象
将响应式对象(或普通对象)转为深层只读代理,任何修改(包括嵌套属性)都会被阻止(开发环境报错)。
适用场景:
- 保护核心配置数据(如全局主题、权限设置)不被意外修改
- 传递不可变数据给子组件
import { reactive, readonly } from 'vue'
const user = reactive({ name: '张三' })
const readOnlyUser = readonly(user)
readOnlyUser.name = '李四' // 报错:无法修改只读对象
5. shallowReadonly
:浅层只读响应式
仅阻止对顶层属性的修改,允许修改嵌套属性(性能优于 readonly
)。
适用场景:只需保护顶层属性,允许嵌套内容被修改的场景。
import { reactive, shallowReadonly } from 'vue'
const obj = shallowReadonly({
a: 1,
nested: { b: 2 }
})
obj.a = 2 // 报错:顶层属性只读
obj.nested.b = 3 // 允许修改嵌套属性(无报错)
6. isRef
/ isReactive
/ isReadonly
:响应式判断工具
用于检测数据是否为响应式类型,辅助开发调试。
import { ref, reactive, readonly, isRef, isReactive, isReadonly } from 'vue'
const count = ref(0)
const user = reactive({ name: '张三' })
const roUser = readonly(user)
console.log(isRef(count)) // true
console.log(isReactive(user)) // true
console.log(isReadonly(roUser)) // true
7. unref
:自动解包 ref
简化 ref
的访问:如果参数是 ref
则返回 .value
,否则直接返回参数。
import { ref, unref } from 'vue'
const count = ref(10)
const num = 20
console.log(unref(count)) // 10(等价于 count.value)
console.log(unref(num)) // 20(直接返回原值)
8. triggerRef
:手动触发 shallowRef 更新
强制 shallowRef
触发响应式更新(即使内部属性变化)。
import { shallowRef, triggerRef } from 'vue'
const data = shallowRef({ count: 0 })
// 修改内部属性后手动触发更新
data.value.count = 1
triggerRef(data) // 强制视图刷新
总结
这些 API 覆盖了响应式处理的不同需求:
- 精细化控制:
shallowRef
/shallowReactive
用于性能优化 - 只读保护:
readonly
/shallowReadonly
用于数据安全 - 工具方法:
isRef
/unref
等用于辅助判断和解包 - 属性转换:
toRef
用于单个属性的响应式提取
实际开发中,它们通常与 reactive
/ref
配合使用,根据数据结构和业务场景选择合适的 API。