Состояние доступа Vuex до завершения асинхронного действия
У меня возникли проблемы, когда вычисляемый геттер обращается к состоянию до его обновления, таким образом, представляя старое состояние. Я уже пробовал некоторые вещи, такие как слияние мутаций с действиями и изменение состояния на множество различных значений, но геттер все еще вызывается до завершения отправки.
Задача
Состояние вызывается до завершения асинхронного действия (вызова api).
Структура кода
- компонент a загружает API данные.
- пользователь нажимает 1 из данных.
- компонент А отправляет щелкнутые данные (объект) компоненту В.
- компонент B загружает полученный объект.
Примечание
DOM делает прекрасно. Это ошибка консоли. Вью всегда следит за тем, чтобы дом менялся и перерисовывался мгновенно. Консоль, однако, забирает все.
Цель
Запретить компоненту B (который вызывается только после компонента) запускать его вычисляемый метод геттера до завершения отправки компонента а.
Магазин.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
searchResult: {},
selected: null,
},
getters: {
searchResult: state => {
return state.searchResult;
},
selected: state => {
return state.selected;
},
},
mutations:{
search: (state, payload) => {
state.searchResult = payload;
},
selected: (state, payload) => {
state.selected = payload;
},
},
actions: {
search: ({commit}) => {
axios.get('http://api.tvmaze.com/search/shows?q=batman')
.then(response => {
commit('search', response.data);
}, error => {
console.log(error);
});
},
selected: ({commit}, payload) => {
commit('selected', payload);
},
},
});
Результат поиска.vue
<template>
<div>
//looped
<router-link to="ShowDetails" @click.native="selected(Object)">
<p>{{Object}}</p>
</router-link>
</div>
</template>
<script>
export default {
methods: {
selected(show){
this.$store.dispatch('selected', show);
},
},
}
</script>
ShowDetails.vue
<template>
<div>
<p>{{Object.name}}</p>
<p>{{Object.genres}}</p>
</div>
</template>
<script>
export default {
computed:{
show(){
return this.$store.getters.selected;
},
},
}
</script>
Вопрос
Vuex-это все о наблюдении за состоянием и управлении, так как я могу предотвратить эту ошибку консоли?
Заранее благодарю.
3 ответов:
store.dispatch
может обрабатывать обещание, возвращаемое обработчиком инициированного действия, и он также возвращает обещание. См. Составление Действий.Вы можете настроить ваше выбранное действие, чтобы вернуть обещание следующим образом:
selected: ({commit}, payload) => { return new Promise((resolve, reject) => { commit('selected', payload); }); }
Затем в результатах поиска .vue вместо использования
router-link
используйте кнопку и выполните программную навигацию в успешном обратном вызове вашего выбранного обещания действия следующим образом:<template> <div> //looped <button @click.native="selected(Object)"> <p>{{Object}}</p> </button> </div> </template> <script> export default { methods: { selected(show){ this.$store.dispatch('selected', show) .then(() => { this.$router.push('ShowDetails'); }); }, }, } </script>
Инициализируйте свои состояния. Как и со всеми другими данными Vue, всегда лучше инициализировать его в начальной точке, даже с пустыми
''
или[]
, но VueJS (не уверен, что Angular или React действуют одинаково, но я предполагаю, что они похожи) будет вести себя намного лучше, когда все ваши переменные инициализированы.Вы можете определить начальное пустое значение ваших состояний в экземпляре магазина.
Вы найдете это полезным не только здесь, но, например, с проверкой форм, так как большинство плагинов будет работать нормально. инициализированные данные, но не будет работать должным образом с неинициализированными данными.
Надеюсь, это поможет.
Вы можете попробовать использовать v-if, чтобы избежать рендеринга шаблона, если это не Результаты поиска
v-if="$store.getters.searchResult"
Comments