shallowref 与 reactive 互斥,不可嵌套混合;shallowref 仅响应 .value 赋值,适用于第三方实例或只读大数据;reactive 默认深度响应,适合结构化状态管理;协作应分层分工、按需选用。

shallowRef 本身不和 reactive “结合”使用——它俩是互斥的响应式策略,不能嵌套或混合来实现所谓“混合响应式”。想用 shallowRef,就放弃对目标值内部的响应式;想用 reactive,就得接受它的深度代理特性。所谓“混合”,其实是根据数据层级和访问模式,在不同变量上**分别选用** shallowRef 或 reactive,让它们在同一个组件或逻辑中协同工作。
shallowRef 的定位很明确
它只对 .value 这一层赋值做响应式追踪:
- 写
chart.value = new ECharts(dom)→ 触发更新 - 但写
chart.value.setOption({})或chart.value._model→ 完全不触发响应式,也不代理内部属性 - 适合包裹第三方重型实例(ECharts、MapLibre、Monaco 等)或超大只读数组
reactive 依然负责结构化状态管理
它保持对自身第一层属性的响应式,且默认递归处理嵌套对象:
Orderly React SDK 钩子使用参考指南,包括 useOrderEntry、usePositionStream、useOrderbookStream、useCollateral 等。
-
const form = reactive({ name: '', email: '' })→form.name = 'a'触发更新 -
form.profile = { avatar: '' }→ 第一层赋值有效;但form.profile.avatar = 'x.jpg'也有效(因为 reactive 默认深度) - 如果你不需要深层响应,才考虑用
shallowReactive替代
实际协作方式:分层分工,各司其职
一个典型电商后台商品编辑页可能这样组织:
-
const editorInstance = shallowRef<monacoeditor null>(null)</monacoeditor>→ 只关心实例是否被替换,不监听它内部 model 或 cursor 变化 -
const formData = reactive({ title: '', desc: '', tags: [] })→ 表单字段需实时校验、联动,需要完整响应式 -
const previewImage = shallowRef<string>('')</string>→ 图片 URL 是基本类型,用 shallowRef 比 ref 更轻量(避免多余 .value 包装) -
const auditLogs = shallowRef<audititem>([])</audititem>→ 10 万条日志只读展示,禁止 Vue 递归代理每一条
注意别踩的坑
以下写法看似“混合”,实则无效或危险:
- ❌
const x = reactive({ chart: shallowRef(...) })→ reactive 会尝试把 shallowRef 对象本身当普通对象代理,破坏 shallowRef 的语义 - ❌
const y = shallowRef(reactive({...}))→ shallowRef 只劫持 .value 赋值,而 reactive 已经在构造时完成了深度代理,白白浪费性能 - ✅ 正确姿势是:该 shallow 就 shallow,该 deep 就 deep,按需选 API,不强行套娃
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









