Search code examples
vue.jsvuex

Strange behaviour of vuex


I have a module in Vuex. It have one sub-level module, so to get chat members I need: this.$store.state.dashboard.chat.members.

I can add this members via mutator, in vue-dev-tools I can see new "members", but in rendered template it not appears.

Module chat.js looks like:

export default {
    namespaced: true,
    state: {
        'members': {}
    },
    getters: {
        members: state => {
            return state.members;
        }
    },
    mutations: {
        addMember(state, member) {
            state.members[member.id] = member;
        }
    }
}

I'm using mapGetters to get members:

 computed: {
  ...mapGetters('dashboard/chat', {
    members: 'members',
 }),

In template I use: <div class="some-class" v-for="user in members">

So, after calling this.addMember from Index.vue of my chat with user information as object I can see this object in vue-dev-tools, but I can't see it on page

When I tried to "time travel to state" which use addMember, before next commited state, I had seen that rendered members list.

The result

Next state was update member online status, which mean just change members[id].is_online value. I tried to remove this mutator, but nothing changed.

Help, please =)


Solution

  • In vue to keep the object properties reactive you should update it using the set method or object.assign. Read more about vue reactivity here.

     mutations: {
            addMember(state, member) {
                let memObj = {}
                memObj[member.id] = member;            
                state.members = Object.assign({}, member);
            }
        }
    

    If you want to change only particular property you can use Vue.set method. Or else in case there are other properties in state.members then you can copy them to memObj and reassign using Object.assign as shown above.