Vue3中对比ref,reactive,shallowRef,shallowReactive
对比ref,reactive,shallowRef,shallowReactive
1. 响应性的深度
API | 响应性范围 | 适用场景 |
---|---|---|
ref | 深层响应(基本类型/对象的所有层级) | 基本类型数据,或需要深层响应的对象/数组 |
reactive | 深层响应(对象/数组的所有层级) | 需要深层响应的复杂对象/数组(如嵌套对象) |
shallowRef | 浅层响应(仅 .value 本身,不处理内部对象) | 大型对象/第三方库实例(避免深层代理的性能开销) |
shallowReactive | 浅层响应(仅对象第一层属性,不处理嵌套对象) | 只需第一层属性响应的对象(如表单的简单字段) |
2. 详细对比与示例
(1)ref
vs shallowRef
-
ref
:对基本类型会创建响应式包装;对对象类型,会自动用reactive
包装,实现深层响应。import { ref } from 'vue'const data = ref({ name: 'Alice', info: { age: 20 } })// 修改深层属性,会触发响应式更新 data.value.info.age = 21 // ✅ 视图会更新
-
shallowRef
:只跟踪.value
的引用变化,不处理内部对象的响应式(即对象内部属性变化不会触发更新)。import { shallowRef } from 'vue'const data = shallowRef({ name: 'Alice', info: { age: 20 } })// 修改深层属性,不会触发更新 data.value.info.age = 21 // ❌ 视图不更新// 只有替换整个 .value 才会触发更新 data.value = { ...data.value, info: { age: 21 } } // ✅ 视图会更新
(2)reactive
vs shallowReactive
-
reactive
:会递归将对象的所有层级属性转为响应式,深层属性变化会触发更新。import { reactive } from 'vue'const user = reactive({name: 'Alice',info: { age: 20 } })// 修改深层属性,会触发更新 user.info.age = 21 // ✅ 视图会更新
-
shallowReactive
:只处理对象的第一层属性,嵌套对象的变化不会触发响应式更新。import { shallowReactive } from 'vue'const user = shallowReactive({name: 'Alice',info: { age: 20 } // 嵌套对象不会被转为响应式 })// 修改第一层属性,会触发更新 user.name = 'Bob' // ✅ 视图会更新// 修改深层属性,不会触发更新 user.info.age = 21 // ❌ 视图不更新
使用浅层响应式
浅层响应式 API(shallowRef
/shallowReactive
)的核心价值是性能优化,适用于以下场景:
- 处理大型对象(如后端返回的复杂数据),避免深层代理带来的性能开销;
- 操作第三方库实例(如 Chart.js、地图库对象),这些对象不需要响应式,且深层代理可能导致异常;
- 明确只需要第一层属性响应的场景(如简单表单),减少不必要的响应式追踪。
总结
场景需求 | 推荐 API |
---|---|
基本类型 + 深层响应 | ref |
复杂对象 + 深层响应 | reactive |
大型对象/第三方实例 + 浅层响应 | shallowRef |
简单对象 + 仅第一层响应 | shallowReactive |
浅层响应式不会递归处理嵌套数据,使用时需手动管理深层变化的响应性(如通过替换整个对象引用)