是否可以在导出的模块中使用Vuex mapActions

时间:2019-06-13 16:32:22

标签: javascript vue.js vuex

是否可以从导入到组件的单独模块中调用Vuex mapActions?

我正在尝试在vue.js Web应用程序中标准化一组功能。我想将它们导入到每个组件中,并传递一些值以进行函数操作。我正在使用vuex来管理状态。当前,每个组件在每次加载时都会调用这些函数(完全相同)。

我想将其重构到一个模块中,然后根据需要将其导入到每个组件中。这段代码使用mapActions作为其功能的一部分。以下是相关的代码片段:组件,模块,vuex操作

Vue组件:

//the imported function call
if (!this.queued){
   timer.updatePage(this.pagination, this.orders);
}

模块代码(advance.js):

import { mapActions } from 'vuex';

let currentComp = {
   name: 'purchase',
   date: null,
   start: false
}

const timer = {
   ...mapActions(['currentComponent']),
   updatePage(pagination, order) {
      currentComp.name = 'nextComponent';
      this.currentComponent(currentComp);
   }
}
export default timer;

vuex代码:

//in the actions section:
currentComponent({
        commit
    }, comp) {
        console.log(comp);
        commit('setCurrentComponent', comp);
}

//in the mutations section:
setCurrentComponent: (state, comp) => {
        state.currentComponent = comp.name;
        return state;
    }

当组件运行导入的功能时,我得到:

vuex.esm.js?2f62:870 Uncaught TypeError: Cannot read property 'dispatch' of undefined
    at Object.mappedAction [as currentComponent] (vuex.esm.js?2f62:870)
    at eval (advance.js?935c:37)

当我从this.currentComponent中删除此内容时,我得到:

advance.js?935c:37 Uncaught ReferenceError: currentComponent is not defined
    at eval (advance.js?935c:37)

提前感谢您的指导。

1 个答案:

答案 0 :(得分:0)

mapActions是创建类似如下方法的快捷方式

currentComponent() {
   this.$store.dispatch('xxx')
}

调用此函数时,this上下文为timer。由于timer没有$store属性,因此会出现错误Cannot read property 'dispatch' of undefined。解决此问题的最快方法是将this上下文更改为确实具有$store属性的组件。您可以通过将组件作为第三个属性传递到updatePage并将currentComponent绑定到该函数来实现。

// component code
timer.updatePage(this.pagination, this.orders, this);

// advance.js
const timer = {
   ...mapActions(['currentComponent']),
   updatePage(pagination, order, component) {
      currentComp.name = 'nextComponent';
      this.currentComponent.bind(component)(currentComp);
   }
}

尽管如此,我还是建议使用mixin进行这种行为。

import { mapActions } from 'vuex';

let currentComp = {
   name: 'purchase',
   date: null,
   start: false
}

const timerMixin = {
   methods: {
       ...mapActions(['currentComponent']),
       updatePage(pagination, order) {
          currentComp.name = 'nextComponent';
          this.currentComponent(currentComp);
       }
   }
}
export default timerMixin;

在您的组件中,导入timerMixin并将其注册为mixin。这些方法将直接在您的组件上可用,您可以通过对现有代码进行一些细微调整来调用它们。

if (!this.queued){
   this.updatePage(this.pagination, this.orders);
}