我遇到的问题是计算的getter在更新之前访问状态,从而呈现旧状态。我已经尝试过一些方法,例如将变量与动作合并,并将状态更改为许多不同的值,但在调度完成之前仍然会调用getter。
问题
在异步操作(api调用)完成之前访问状态。
代码结构
注意
DOM呈现得很好。这是一个CONSOLE ERROR。 Vue始终关注DOM更改并立即重新呈现。然而,控制台会接收所有内容。
目标
防止组件B(仅称为AFTER组件)在组件A的分派完成之前运行其计算的getter方法。
Store.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);
},
},
});
SearchResult.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是关于状态观察和管理的,所以如何防止此控制台错误?
提前致谢。
答案 0 :(得分:5)
store.dispatch
可以处理触发的动作处理程序返回的Promise,它也返回Promise。请参阅Composing Actions。
您可以设置所选操作以返回此类承诺:
selected: ({commit}, payload) => {
return new Promise((resolve, reject) => {
commit('selected', payload);
});
}
然后在 SearchResults.vue 中,而不是使用router-link
使用按钮,并在所选操作的成功回调中执行programmatic navigation承诺这样:
<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>
答案 1 :(得分:1)
如果没有搜索结果,您可以尝试使用v-if来避免渲染模板
v-if="$store.getters.searchResult"
答案 2 :(得分:0)
初始化您的州。
与所有其他Vue&#39;一样数据总是更好地在起始点初始化它,即使是空''
或[]
但是VueJS(不确定Angular或React行为是否相同,但我认为相似)会表现得更好所有的变量都已初始化。
您可以在商店实例中定义状态的初始空值。
您会发现这不仅对此有帮助,而且例如使用表单验证,因为大多数插件可以正常使用初始化数据,但无法正常使用非初始化数据。
希望它有所帮助。