triggerref 是手动通知 vue 更新 shallowref 内部变更的轻量级方案,适用于直接修改对象属性但需避免整体赋值的场景,仅对 shallowref 有效且调用时须传入 ref 变量本身。

triggerRef 是专门用来手动通知 Vue:这个 shallowRef 的值内部变了,该更新视图了。它不自动监听深层修改,所以必须你来“点一下”才生效。
什么时候必须用 triggerRef?
当你用 shallowRef 包裹了一个对象(比如用户信息、配置项、大型列表),又直接改了它内部的某个字段,但页面没反应——这时候就该 triggerRef 了。
- shallowRef 只响应
.value = 新对象这种整体赋值,不响应.value.name = '新名字'这类内部修改 - 如果你改的是对象或数组的属性、元素,且不想重新赋整个
.value,triggerRef 就是轻量级补救方案 - 特别适合大数据结构(如含上千条目的列表、地图坐标对象),避免频繁替换整个引用带来的内存压力
怎么正确调用 triggerRef?
很简单:改完内部属性后,把对应的 shallowRef 变量传给 triggerRef() 即可。它不接受其他参数,也不返回值。
- ✅ 正确:
userInfo.value.age = 26; triggerRef(userInfo); - ❌ 错误:
triggerRef(userInfo.value);(传错参数,会报错) - ❌ 错误:
triggerRef();(漏传参数,无效) - ⚠️ 注意:只对 shallowRef 有效;shallowReactive 没有 triggerRef,得靠替换顶层引用或配合 reactive 处理子对象
配合使用的小技巧
单独用 triggerRef 很直接,但搭配其他方式更灵活、更可控:
- 局部深度响应:对需要频繁修改的子对象单独用
reactive(),比如const detail = reactive(userInfo.value.profile) - 避免重复触发:一次修改多个字段后,只调一次 triggerRef 即可,不用每改一个就触发一次
- 和 toRaw 配合读取原始值:修改前可用
toRaw(shallowRefVar.value)获取非代理对象,避免意外触发依赖 - 调试时加日志:在 triggerRef 前后打 log,确认修改是否发生、触发是否及时,能快速定位“改了但没更新”的问题
什么情况不用 triggerRef?
不是所有修改都需要它。先判断是不是走错了路:
- 如果只是简单值(字符串、数字、布尔),用 ref 更合适,它天然支持内部变化响应
- 如果数据结构不大(比如不到 10 层嵌套、几十个字段),用 reactive 或 ref 更省心,不用手动维护触发逻辑
- 如果深层字段修改很频繁,且业务逻辑允许,直接替换
.value更清晰,比如list.value = [...list.value, newItem] - 第三方实例(如 Canvas、Three.js 对象)本就不该响应式更新,用 markRaw + shallowRef 即可,无需 triggerRef










