Props watch 在 Vue 组合 api 中不起作用

PA-*_*-GW 3 vue.js vuejs3 vue-composition-api

我有一个state对象作为另一个组件的道具传递。我收到了state预期的结果。然后我将其存储props在 a 中toRef()以进行反应。

我想要发生的是当数据发生state变化时,我希望浏览器中的数据进行更新。现在,数据确实在 vue 开发工具中更新,并且我确实看到了state对象更改,但浏览器不会反映更改,直到我手动刷新浏览器,这是一个不希望的结果。

为什么会发生这种情况:

成分:

<template>
      <div class="show-products">
        <Product
            v-for="data in products"
            :key="data.id"
            :product="data"
        />
      </div>
 </template>

<script>
import {computed, onMounted, toRefs, watch } from "vue";
import {useStore} from "vuex";
    
    export default {
      components: {Product},
      props: {
        state: Object
      },
      setup (props) {
        const store = useStore();
        const products = computed(() => store.getters.getProducts);
    
        let stateRef = toRefs(props).state;
    
        onMounted(() => {
          store.dispatch('getProducts');
        });
    
        watch(stateRef, (currentState, prevState) => {
          if (currentState.length !== prevState.length) {
            store.dispatch('getProducts');
          }
        })
    
        return {
          Product,
          products,
        }
      }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

ton*_*y19 14

观察数组长度需要深度观察器,因此请确保设置标志deep

watch(stateRef, (currentState, prevState) => {/*...*/}, { deep: true })
Run Code Online (Sandbox Code Playgroud)

此外,观察者回调仅接收数据引用,因此如果您仅更改原始数组(例如,通过push()pop()),则currentStateprevState参数将是相同的引用,这将导致长度检查失败。

一个潜在的解决方案是删除长度检查,并始终getProducts在观察者中调度操作:

// ProductList.vue
watch(stateRef, (currentState, prevState) => {
  store.dispatch('getProducts')
}, { deep: true })
Run Code Online (Sandbox Code Playgroud)

另一个不需要深度观察程序的解决方案是为 state 分配一个新数组,而不是在原始数组上使用push()/ :pop()

// Parent.vue
addState(newValue) {
  state.value = [ ...state.value, newValue ]
}
Run Code Online (Sandbox Code Playgroud)

演示