VueX的商店还可以向组件发出事件吗?

时间:2019-09-20 19:16:31

标签: vue.js vuex

我有以下组件树:

App
  List
  ItemDetails
    Widget1
    ...
  • List组件具有过滤器表单,这些过滤器应用于按钮按下时
  • Widget1有一个按钮,该按钮将另一个过滤器(通过id)应用于列表,应用该过滤器将从过滤器表单中删除过滤器,反之亦然
  • 该列表还通过轮询实时更新(以后将通过WebSockets更新),因此我必须将v-model中的List个过滤器字段与实际应用的过滤器分开(这些过滤器位于商店)

当前,我已将以下状态放入VueX存储:

state: {
    filters: {
        // these come from the List's filter panel
        result: '',
        name: '',
        date: '',
        // this one comes from Widget1
        id: '',
    },
    pagination: {
        perPage: 10,
        page: 0,
        total: 0,
    },
    items: [],

    selectedItem: null,
},

以及通过向商店调度以下操作来应用ListWidget1中按钮的两个过滤器:

applyFilters ({ state, commit, dispatch }, filters) {
    if(filters.id) {
        for(let filterName in state.filters)
            if(filterName !== 'id')
                filters[filterName] = '';
    } else {
        filters.id = '';
    }
    commit('setFilters', filters);
    commit('setPage', 0);
    dispatch('loadExaminations');
},

但这是问题所在:List组件具有其过滤字段模型(按下按钮将收集这些字段并分派applyFilters)。除应用了来自Widget1的id过滤器之外,List组件中的过滤器字段不会为空。

处理此问题的一个明显选择是将那些过滤器字段的模型也移至商店。这看起来不太好,因为对于每个字段(使用v-model),我必须创建一个computed(在List组件中)并从商店中编写一个setter和getter 。将事件从applyFilters发送到List似乎更好,但是我不确定VueX是否可以做到这一点。 这可能吗?还是应该坚持“将过滤器字段的模型移至商店”计划?还是您知道一个不错的选择?我知道event bus的概念,但是我猜想它使用Vue实例,不应在商店中使用。

1 个答案:

答案 0 :(得分:1)

您可以使用subscribeAction收听vuex的操作。

// List.vue
mounted() {
    this.$store.subscribeAction({
      before: (action, state) => {
        if (action.type === "applyFilters" && action.payload.id) {
          this.emptyComponentFields();
        }
      },
      after: (action, state) => {}
    });
  }

CodeSandbox