vuejs2 - Vuex 中的参数化 getter - 触发 udpate
问题描述
我的 Vuex 商店有一组数据,比如 1000 条记录。有一个带有参数 getItem 的 getter,它获取一个 ID 并返回正确的记录。
我需要访问该 getter 的组件来了解数据何时准备就绪(当所有记录的异步获取完成时)。
然而,由于它是一个参数化的 getter,Vue 不会监视它所依赖的状态以了解何时更新它。我应该怎么办?
我一直想恢复到我在 Angular 中经常使用的 BehaviorSubject 模式,但是 Vuex + rxJS 似乎很重,对吧?
我觉得我需要以某种方式发出一个触发器让 getter 重新计算。
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import VueResource from 'vue-resource'
Vue.use(VueResource);
Vue.use(Vuex)
export default new Vuex.Store({
state: {
numberOfPosts : -1,
posts : {}, //dictionary keyed on slug
postsLoaded : false,
},
getters : {
postsLoaded : function(state){
return state.postsLoaded;
},
totalPosts : function(state){
return state.numberOfPosts;
},
post: function( state ){
return function(slug){
if( state.posts.hasOwnProperty( slug ) ){
return state.posts.slug;
}else{
return null;
}
}
}
},
mutations: {
storePosts : function(state, payload){
state.numberOfPosts = payload.length;
for( var post of payload ){
state.posts[ post.slug ] = post;
}
state.postsLoaded = true;
}
},
actions: {
fetchPosts(context) {
return new Promise((resolve) => {
Vue.http.get(' {url redacted} ').then((response) => {
context.commit('storePosts', response.body);
resolve();
});
});
}
}
})
Post.vue
<template>
<div class="post">
<h1>This is a post page for {{ $route.params.slug }}</h1>
<div v-if="!postsLoaded">LOADING</div>
<div v-if="postNotFound">No matching post was found.</div>
<div v-if="postsLoaded && !postNotFound" class="post-area">
{{ this.postData.title.rendered }}
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'post',
data : function(){
return {
loading : true,
postNotFound : false,
postData : null
}
},
mounted : function(){
this.postData = this.post( this.$route.params.slug );
if ( this.postData == null ){
this.postNotFound = true;
}
},
computed : mapGetters([
'postsLoaded',
'post'
])
}
</script>
就目前而言,它显示“未找到帖子”消息,因为当它访问 getter 时,数据还没有准备好。如果找不到帖子,我需要区分 (a) 数据已加载且没有匹配的帖子,以及 (b) 数据未加载,因此请稍候
解决方案
我怀疑问题在于您如何在 storePosts 突变中设置帖子数组,特别是这一行:
state.posts[ post.slug ] = post
VueJs 无法跟踪该操作,因此无法知道数组已更新,因此您的 getter 未更新。
相反,您需要像这样使用 Vue 集:
Vue.set(state.posts, post.slug, post)
有关详细信息,请参阅更改检测警告文档
推荐阅读
- android - _TypeError(类型'列表
' 不是 'PlaceDetails' 类型的子类型) - c - 在 C 中声明并稍后定义一个数组
- delphi - 如何防止 TStrings.SaveToStream 写入 BOM?
- python - 列表元素的代数运算
- amazon-web-services - 无论如何要将火花分区写入不同的子路径?
- python - 面对 MASK RCNN 中的此错误“未定义名称‘COCO’”
- python - 计算 numpy.array 对象在 numpy.array 对象列表中的出现
- sql - 如何将标识列而不是常量插入到该列不是标识列的表中?
- gmail-api - “也将过滤器应用于匹配的对话” gmail 过滤器 api
- python - django 多对多与三个表关系在一起