Vuex不更新Vue计算属性

时间:2019-06-03 16:07:11

标签: javascript vue.js google-cloud-firestore vuex

我正在尝试将vuex用作Firestore和vue应用程序之间的层。 我的vuex商店看起来像这样:

const store = new Vuex.Store({
    state: {
        posts: [],
    },

    mutations: {
        add_post(state, post) {
            state.posts[post.id] = post;
        },
    },

    actions: {
        async load_post(context, id) {
            let post = await db
                .collection('posts')
                .where('post_id', '==', id)
                .get();
            post = post.docs[0]; 

            post = {id, ...post.data()};
            context.commit('add_post', post);
        },
    }
});

在我的Vue组件中:

export default {
    name: 'Post',
    beforeMount() {
        const id = this.$route.params.id;
        this.$store.dispatch('load_post', id);
    },
    data() {
        return {
            id: this.$route.params.id
        };
    },
    computed: {
        content() {
            return this.$store.state.posts[this.id];
        }
    }
};

现在,在浏览网站时,该代码似乎可以正常运行。但是,如果刷新页面,则content属性将变为未定义。经过一些调试之后,我得出的结论是,它试图在加载时从存储中读取(因此未定义),但是当存储准备就绪时,不会进行任何更新。 到目前为止,我已经尝试了观察者,vuex的mapState,似乎没有任何作用……有什么建议吗?

2 个答案:

答案 0 :(得分:0)

这是Vue反应性问题。您应该在vuex中修改state.posts以使组件具有反应性。突变state.posts[post.id]不会使组件具有反应性,因为state.posts仍指向旧参考。

mutations: {
  add_post(state, post) {
      state.posts = {
        ...state.posts,
        [post.id]: post
      }
  },
},

或者您可以使用JSON.parse(JSON.stringify())

add_post(state, post) {
  state.posts[post.id] = post;
  state.posts = JSON.parse(JSON.stringify(state.posts))
},

答案 1 :(得分:0)

Vue无法检测到嵌套属性的更改,该属性未在加载状态下设置。尝试将您的突变更改为此:

add_post(state, post) {
   Vue.set(state.posts, post.id, post);
}

// You need to import Vue at the top of your store file, when using the Vue.set() method
import Vue from 'vue';