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

Vue中watch无法配合Pinia与组合式API工作的问题

Pinia中watch监听数组不生效的问题解决

问题代码

store.js

export default defineStore('global', () => {
    const packagesList = reactive([])
    
    function getSearch() {
        setTimeout(() => {
            packagesList.splice(0, packagesList.length, ...[1,2,3])
        }, 1000);
    }
  
    return { packagesList, getSearch}
})

组件代码

<script setup>
import { watch } from 'vue'
import { storeToRefs } from 'pinia'
import Store from '@/store/index'

const store = Store()
const { packagesList } = storeToRefs(store)

setTimeout(()=>{
  store.getSearch()
},1000)

watch(
  () => packagesList,
  {deep: true},
  (count, prevCount) => {
    console.log(count, prevCount)
  }
)
</script>

问题原因

watch监听目标写法错误:

  • storeToRefs返回的packagesList是Ref对象,当前监听的是这个Ref对象的引用本身,而非其内部包裹的数组实例。
  • 即便开启deep: true,这种写法也无法触发数组内部元素变化的监听,因为Ref的value属性才是实际要监听的数组。

修复方案

有两种正确写法可选:

方案1:直接传入Ref对象作为监听源

watch(
  packagesList, // 直接监听Ref对象
  { deep: true },
  (count, prevCount) => {
    console.log(count, prevCount)
  }
)

方案2:监听Ref的value(数组本身)

watch(
  () => packagesList.value, // 监听数组实例
  { deep: true },
  (count, prevCount) => {
    console.log(count, prevCount)
  }
)

补充说明

数组是引用类型,使用splice修改内部元素属于深层变化,因此必须开启deep: true才能触发监听。如果是直接替换整个数组(如packagesList.value = [1,2,3]),则无需配置deep。

内容的提问来源于stack exchange,提问作者Dmytro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:42:59