Vue / Vuex-模块二取决于模块一,模块一从服务器获取数据

时间:2019-05-11 19:01:58

标签: javascript asynchronous vue.js vuex

检查一下:

import accountModule from '@/store/modules/account/account';
import otherModule from '@/store/modules/other/other';

export default new Vuex.Store({
  modules: {
    account: accountModule,
    other: otherModule,
  }
});

other模块中的数据初始化取决于account模块,因为account模块具有用户特定的设置。假设other.state.list依赖于account.state.settings.listOrder。但是,我希望account模块的数据来自服务器。这是异步的。因此,当other试图进行设置时,它不能仅仅尝试引用account.state.settings.listOrder,因为服务器的响应可能还没有回来。

我尝试导出accountModule中的 promise ,该问题与模块本身一起解决。但是这种方法似乎行不通。

import accountModulePromise from '@/store/modules/account/account';

accountModulePromise.then(function (accountMoudle) {
  import otherModule from '@/store/modules/other/other';

  ...
});

这给我一个错误,说import语句需要是顶级的。

以下方法也不起作用:

let accountModule = await import '@/store/modules/account/account';
import otherModule from '@/store/modules/other/other';
...

给我一​​个错误,说await是保留字。不过我很困惑,因为https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import说我应该能够做到。

2 个答案:

答案 0 :(得分:0)

由于await必须位于async函数中,因此您的最后一个代码块不起作用。

  

请记住,await关键字仅在异步函数内有效。如果   在异步函数的主体之外使用它,您将获得一个   语法错误。

来自MDN

您可以使用Dynamic Module Registration

accountModulePromise.then(async () => {
  let otherModule = await import('@/store/modules/other/other');
  store.registerModule('other', otherModule.default);
});

但是,当您要获取状态或调度动作时,必须检查模块是否已注册,这很糟糕。

我认为最好重新设计模块结构以使彼此解耦。尝试将您的初始化代码移至main.jsApp.vue,然后分派操作以从中更新模块状态。


更新

从上次更新(将商店脱钩的另一种想法)开始,我认为您应该无顺序存储list并仅在使用时对其进行排序。您可以执行以下操作:

计算属性:

...
computed: {
  list () {
    let list = this.$store.state.other.list
    let order = this.$store.state.account.settings.listOrder
    if (!list || !order) return []
    return someSort(list, order)
  }
},

beforeCreate () {
  this.$store.dispatch('other/fetchList')
  this.$store.dispatch('account/fetchListOrder')
}
...

或Vuex吸气剂:

...
getters: {
  list: (state) => (order) => {
    return someSort(state.list, order)
  }
}
...
...
computed: {
  list () {
    let order = this.$store.state.account.settings.listOrder
    return this.$store.getters['others/list'](order)
  }
}
...

答案 1 :(得分:0)

好的,所以您有两个模块。一个从服务器获取的状态,另一个则取决于第一个正确的状态?

我建议采用以下方法:

首先将模块设置为空的“状态”。然后在accountModule中创建一个操作,以设置服务器的状态。在other上使用吸气剂对列表进行排序。最后,在创建应用程序时调度您的操作。

const account = {
    namespaced: true,
    state: {
        listOrder: ''
    },
    mutations: {
        setListOrder (state, newListOrder) {
            state.listOrder = newListOrder
        }
    },
    actions: {
        async fetchServerState (ctx) {
            let result = await fetch("/path/to/server")
            ctx.commit('setListOrder', result.listOrder) 
            // or whatever your response is, this is an example
        }
    }
}

const other = {
    namespaced: true,
    state: {
        unorderedList: []
    },
    getters: {
        list (state, getters, rootState) {
            return someSort(state.unorderedList, rootState.account.listOrder);
        }
    }
}


在App.vue中(或任何地方)

created () {
    this.$store.dispatch('account/fetchServerState')
}