Vue / Vuex - модуль два зависит от модуля один, а модуль один получает данные с сервера - PullRequest
3 голосов
/ 11 мая 2019

Проверьте это:

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, которое разрешается с помощью самого модуля. Но такой подход, похоже, не работает.

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 голосов
/ 20 мая 2019

Хорошо, у вас есть два модуля. Один с состоянием, которое выбирается с сервера, другой с состоянием, которое зависит от первого, верно?

Я бы предложил следующий подход:

Для начала настройте ваши модули с пустым «состоянием». Затем создайте действие в accountModule для настройки состояния с сервера. Используйте getter на 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')
}
0 голосов
/ 12 мая 2019

Ваш последний блок кода не работал, потому что await должен быть внутри функции async.

Помните, ключевое слово await допустимо только внутри асинхронных функций.Если вы используете его вне тела асинхронной функции, вы получите SyntaxError.

От MDN .

Вы можете использовать Регистрация динамического модуля:

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

Но когда вы хотите получить действия состояния или отправки, вы должны проверить, зарегистрирован ли модуль, что довольно плохо.

По моему мнению, было бы лучше, еслиВы изменяете структуру модуля так, чтобы отделить друг друга.Попробуйте переместить инициализирующий код в main.js или App.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)
  }
}
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...