Есть ли способ загрузить все данные для хранилища vuex один раз, но загружать их только при необходимости?
Я предполагаю, что есть, но я борюсь, и я не уверен, что это потому, что яЯ неправильно понимаю Vuex или Async / Await в обещаниях Javascript.
Это пример магазина для Roles
.userRolesApi
делает запрос axios и возвращает обещание.
import {userRolesApi} from "../api";
export default {
actions: {
setRoles(context, roles) {
context.commit('SET_ROLES', roles)
},
async loadRoles({state, dispatch}) {
if (state.all === null) {
return await userRolesApi.index().then(response => {
dispatch('setRoles', response.data)
})
}
}
},
state: {
all: null
},
getters: {
findRoleFromId: (state) => (role) => {
return _.find(state.all, {id: parseInt(role)})
},
findRoleFromName: (state) => (role) => {
return _.find(state.all, {name: role})
}
},
mutations: {
SET_ROLES (state, roles) {
state.all = roles
},
}
}
Что я хотел бы сделать, это вызвать findRoleFromId
из компонента Vue.
Это тогда получитроль из массива ролей в состоянии state.all
, но также создайте этот массив из API, если он еще не существует.
Из того, что я могу сказать, это плохая практика - вместо этого делать запросы API изнутри геттерамиВместо этого у меня есть метод loadRoles
в действии.
Но я не могу вызвать действие из получателя, поэтому теперь мне придется вызывать loadRoles
откуда-то еще, каждый раз, когда ядумаю, мне, возможно, понадобится использовать роль.
Поэтому я получаю такой компонент:
mounted() {
this.$store.dispatch('loadRoles')
},
computed: {
role() {
// This will be null at first but update once the api request finishes.
return this.$store.getters.findRoleFromId(this.roleId)
}
},
Это на самом деле прекрасно работает!
Однако, если по какой-то причинеЯ вызываю this.$store.dispatch('loadRoles')
в двух компонентах в быстрой последовательности, тогда он дважды сделает запрос API.
Я попытался решить эту проблему с помощью async / await, но, похоже, это не имеет значения, это не такостановите обработку до завершения запроса.
В качестве теста изменив мой компонент на это:
mounted() {
this.$store.dispatch('loadRoles')
this.$store.dispatch('loadRoles')
this.$store.dispatch('loadRoles')
this.$store.dispatch('loadRoles')
},
computed: {
role() {
return this.$store.getters.findRoleFromId(this.roleId)
}
},
Вызывает запрос API, который будет вызван 4 раза мгновенно.Вместо того, чтобы ждать, пока закончится первый, а затем со второй попытки, не пройдя проверку state.all === null
и не сделав запрос API.
Я пытался быть настолько многословным, насколько это возможно, объясняя, что это такое.Я пытаюсь сделать, потому что я не уверен, где это, я иду не так.Отсюда мои вопросы:
- Каков наилучший способ заполнить магазин vuex только тогда, когда это необходимо?
- Если мой подход - хороший способ сделать это, что не так смоя попытка асинхронного / ожидания?