shallowRef用于创建浅层响应式引用,仅在.value被整体替换时触发更新,适用于不需深度监听的大对象或第三方实例。

shallowRef 用于创建一个“浅层响应式”的引用,它只对 .value 属性的赋值(即替换整个值)触发响应,而不会递归地使内部属性变成响应式。
什么时候该用 shallowRef?
当你有一个大对象(比如含大量嵌套属性或数组项),但你**只关心这个对象整体被替换的时机**,不希望 Vue 深度监听它的每一个字段变化时,就适合用 shallowRef。常见于:
- 第三方库返回的复杂实例(如 Canvas、Map、编辑器 editor 实例)
- 从 API 获取的原始 JSON 数据,后续只做整体更新,不频繁修改深层字段
- 避免因深度响应式带来的性能开销(尤其对象层级深、属性多)
基本用法:创建与读写
和 ref 类似,但响应行为不同:
const state = shallowRef({ a: 1, b: { c: 2 } })
state.value = { a: 2 } // ✅ 替换整个 value,视图响应更新
❌ 不触发更新:
state.value.a = 3 // ❌ 修改属性,不触发响应 state.value.b.c = 4 // ❌ 深层修改,完全无响应
在模板中怎么用?
和普通 ref 一样,直接解构或访问 .value(模板中可省略 .value):
<template><div>{{ state.a }}</div> <!-- 模板中自动解包,但注意:这里只是读取,不是响应式读取!-->
</template><p><script setup>
import { shallowRef } from 'vue'
const state = shallowRef({ a: 1 })
// 若想让模板响应式显示 a,必须通过 .value 整体替换:
// state.value = { a: 2 }
</script></p>
⚠️ 注意:模板中 {{ state.a }} 能显示是因为 Vue 自动读取了 state.value,但它不会监听 state.value.a 的变化 —— 所以如果只改 a 字段,页面不会更新。
和 ref / shallowReactive 的区别
-
ref(obj):深度响应式,任何嵌套属性修改都会触发更新(有性能成本) -
shallowRef(obj):仅.value = 新对象才响应,适合“整替”场景 -
shallowReactive(obj):没有.value,直接操作对象,但仅顶层属性赋值响应(深层仍不响应)











