You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在Pinia仓库的Vue监听器中必须指定deep: true?

问题解答

首先得明确Vue文档里说的「直接对响应式对象调用watch()时隐式创建深度监听器」,指的是监听reactive创建的响应式对象的场景,比如:

const obj = reactive({ bar: 1 })
watch(obj, () => console.log('变更触发')) // 此时修改obj.bar会触发监听,无需deep

而你的代码里,foo是用ref包裹的对象,这和上面的场景本质不同:

  • ref的响应式是针对.value的引用变化的,也就是说只有当你替换整个.value(比如foo.value = { bar: 2 })时,watch(foo)才会触发。
  • 当你只修改.value内部的属性(比如foo.value.bar++),这属于对象内部的嵌套变更,watch(foo)默认只会监听.value的引用是否改变,不会深入到对象内部,所以必须手动加上{ deep: true }才能监听到这类变更。

至于storeToRefs()的作用,它只是保证你从Pinia store里解构出来的foo依然是一个响应式的ref,不会丢失响应式关联,但它改变不了Vue watch的监听规则——watch监听ref时,默认还是只关注其.value的引用变化,而非内部对象的属性变化。

如果不想用deep: true,除了你提到的替换整个.value的方式,还有两种更精准的方案:

  • 直接监听对象的具体属性:
watch(() => foo.value.bar, (newVal) => {
  console.log('bar变更了:', newVal)
})
  • 把store里的foo改成reactive对象(如果适合你的业务场景):
// store.js
const foo = reactive({ bar: 1 })
watch(foo, () => console.log({ foo })) // 此时修改foo.bar会自动触发监听,无需deep

内容的提问来源于stack exchange,提问作者Minh Nghĩa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:35:21