组件道具会根据一种Vuex状态的变化重新评估

时间:2019-11-12 10:59:12

标签: vue.js vuejs2 vue-component vuex

我有两个具有亲子关系的组成部分。使用v-for循环,父组件可以包含任意数量的子组件。

基本上,子组件包含一个引导表b-table,而父组件只是子组件的包装。因此,父组件内部可以具有任意数量的表。

表具有检查或取消检查表中各行的功能。我想跟踪父组件内所有表的所有选定行。我正在使用Vuex存储来保留所有表中所有选定行的id。在选中/取消选中任何行之后,每个子组件都将提交到vuex存储。到这里一切都很好。使用vue devtools,我可以确认vuex存储中始终有正确的数据。 (vuex状态属性名称为selectedObjects,它是一个字符串数组)。

现在,我想基于vuex存储值(使用v-show)在父组件上显示一些数据。我只想在存储中的selectedObjects不是空数组时显示数据。

我有一个从商店中获取selectedObjects状态的吸气剂,并且我使用mapGetters在父组件中将此吸气剂用作计算属性。

问题在于,每当子组件对vuex存储进行任何更改时,父组件都会刷新传递给子组件的prop。传递的prop完全不依赖vuex存储。

<template>
  <div>
    <div v-if="isDataLoaded">
      <div>
        <div>
          <div>
            <span v-show="showBulkActions"> Action1 </span>
            <span v-show="showBulkActions"> Action2 </span>
            <span v-show="showBulkActions"> Action3 </span>
            <span v-show="showBulkActions">Action4</span>
            <span> Action5 </span>
          </div>
        </div>
      </div>
      <div>
        <template v-for="objectId in objectIds">
          <ObjectList
            :key="objectId"
            :objects="getObjectsFor(objectId)"
            :payload="payload"
          ></ObjectList>
        </template>
      </div>
    </div>    
  </div>
</template>

<script>

export default {
  props: {
    payload: Object,
    isDataLoaded: false
  },
  data() {
    return {
            objectIds: [],
            objects: []
    };
  },
  computed: {
    ...mapGetters(["getSelectedObjects"]),
    showBulkActions() {
            // return true; --> works fine

            //This does not work as expected
      const selectedObjects = this.getSelectedObjects;
      return selectedObjects.length > 0;
    }
    },

  mounted: async function() {
    // init this.objects here
    },

  methods: {
    ...mapGetters(["getObjects"]),
    getObjectsFor(objectId) {
            //this line gets executed everytime the selectedObjects is modified in vuex store.
            //this method is only being called from one place (prop of ObjectList component)
      return this.objects.filter(f => f.objectId === objectId);
        }
  }
};
</script>

根据我的理解,更改vuex存储中的getObjectsFor数组时不应调用selectedObjects方法,因为它不依赖于它。

为什么会这样?

1 个答案:

答案 0 :(得分:1)

您的父组件模板取决于selectedObjects Vuex存储值(通过showBulkActions计算的prop和getSelectedObjects getter作为计算的prop)。

每次selectedObjects的存储更改,上级组件的更新(和重新渲染)都会触发。

Vue documentation中所述:

  

每次父组件更新时,子组件中的所有道具都会刷新,并带有最新值

这意味着需要填充用于填充子组件属性的表达式(在您的情况下为getObjectsFor方法的调用)。这就是调用您的方法的原因。

解决方案是将所有对象作为道具传递给子组件,并在子组件内部进行过滤(在getObjectsFor方法中进行过滤)作为计算道具...