vue3 响应式系统指南
-
浅层响应式 API
shallowRef
用于创建仅跟踪顶层值变化的响应式引用。当需要处理大型对象但只关心顶层属性变化时,可显著提升性能。例如:javascript
const state = shallowRef({ user: { name: 'John', age: 30 }, count: 0 }) // 修改顶层属性触发更新 state.value.count = 1 // 嵌套属性修改不触发更新 state.value.user.age = 31
shallowReactive
创建仅第一层属性响应式的对象。适用于树状数据结构的局部更新场景:javascript
const tree = shallowReactive({ root: { id: 1, children: [] } }) // 直接修改顶层属性触发响应 tree.root.id = 2 // 嵌套对象修改不触发响应 tree.root.children.push({ id: 2 })
性能对比
操作类型 shallowRef ref 赋值操作 O(1) O(n) 嵌套属性修改 不触发更新 触发深层更新 -
只读响应式 API
readonly
创建深度只读的响应式对象,所有嵌套属性均不可修改:javascript
const config = readonly({ theme: 'dark', debug: false }) // 开发环境报错,生产环境静默失败 config.theme = 'light'
shallowReadonly
创建浅层只读对象,仅保护顶层属性:javascript
const settings = shallowReadonly({ user: { name: 'John' }, system: { version: '1.0' } }) // 允许修改嵌套属性 settings.user.name = 'Tom' // 禁止修改顶层属性 settings.system = { version: '2.0' } // 报错
-
原始对象操作
toRaw
获取响应式对象的原始值,直接操作原始值不会触发更新:javascript
const reactiveState = reactive({ count: 0 }) const rawState = toRaw(reactiveState) // 直接操作原始对象不会触发更新 rawState.count = 10
markRaw
标记对象使其永不成为响应式,常用于第三方库对象或静态数据:javascript
// Mock数据预处理 const mockData = markRaw(generateMockData()) // 第三方库对象 const externalLib = markRaw(import('external-lib'))
-
自定义 ref
通过customRef
创建具有自定义逻辑的响应式引用,例如防抖输入:javascript
// useDebouncedRef.js import { customRef } from 'vue' export function useDebouncedRef(value, delay = 300) { let timeout return customRef((track, trigger) => { return { get() { track() return value }, set(newValue) { clearTimeout(timeout) timeout = setTimeout(() => { value = newValue trigger() }, delay) } } }) } // 在组件中使用 const searchQuery = useDebouncedRef('')
-
响应式判断工具
提供一组工具函数用于检查响应式对象类型:javascript
import { isRef, isReactive, isReadonly, isProxy } from 'vue' const state = reactive({ count: 0 }) const readonlyState = readonly(state) console.log(isReactive(state)) // true console.log(isReadonly(readonlyState)) // true console.log(isProxy(readonlyState)) // true
-
最佳实践建议
-
性能优化
- 对大数据对象优先使用
shallowReactive
- 只读配置项使用
readonly
或shallowReadonly
- 避免过度使用深度响应式
- 对大数据对象优先使用
-
数据安全
- 关键配置使用
readonly
防止误修改 - 外部库对象使用
markRaw
避免响应式开销
- 关键配置使用
-
逻辑封装
- 通过
customRef
实现防抖、节流等自定义逻辑 - 结合
shallowRef
创建轻量级响应式状态
- 通过
-
通过合理运用这些响应式 API,可以在保证数据正确性的同时显著提升应用性能。建议根据具体场景选择合适的响应式方案,在深度响应与性能开销之间找到平衡点。