最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vuex Mutation running, but component not updating until manual commit in vue dev tools - Stack Overflow

programmeradmin4浏览0评论

I have a vue ponent that I can't get to update from a puted property that is populated from a service call.

Feed.vue

<template>
    <div class="animated fadeIn">
        <h1 v-if="!loading">Stats for {{ feed.name}}</h1>      
        <h2 v-if="loading">loading {{ feedID }}</h2> 
    </div>
</template>
<script>
    export default {
        data: () => {
            return {
                feedID: false
            }
        },
        puted: {
            feed(){
                return this.$store.state.feed.currentFeed
            },
            loading(){
                return this.$store.state.feed.status.loading;
            }
        },
        created: function(){    
            this.feedID = this.$route.params.id;
            var fid = this.$route.params.id;
            const { dispatch } = this.$store;
            dispatch('feed/getFeed', {fid});
        }
    }
</script>

That dispatches 'feed/getFeed' from the feed module...

feed.module.js

import { feedStatsService } from '../_services';
import { router } from '../_helpers';

export const feed = {
    namespaced: true,
    actions: {
        getFeed({ dispatch, mit }, { fid }) {
            mit('FeedRequest', {fid});
            feedStatsService.getFeed(fid)
                .then(
                    feed => {
                        mit('FeedSuccess', feed);
                    },
                    error => {
                        mit('FeedFailure', error);
                        dispatch('alert/error', error, { root: true });
                    }
                )
        }
    },
    mutations: {
        FeedRequest(state, feed) {
            state.status = {loading: true};
            state.currentFeed = feed;
        },
        FeedSuccess(state, feed) {
            state.currentFeed = feed;
            state.status = {loading: false};
        },
        FeedFailure(state) {
            state.status = {};
            state.feed = null;
        }
    }
}

The feedStatsService.getFeed calls the service, which just runs a fetch and returns the results. Then mit('FeedSuccess', feed) gets called, which runs the mutation, which sets state.currentFeed=feed, and sets state.status.loading to false.

I can tell that it's stored, because the object shows up in the Vue dev tools. state.feed.currentFeed is the result from the service. But, my ponent doesn't change to reflect that. And there is a payload under mutations in the dev tool as well. When manually mit feed/feedSuccess in the dev tools, my ponent updates.

What am I missing here?

I have a vue ponent that I can't get to update from a puted property that is populated from a service call.

Feed.vue

<template>
    <div class="animated fadeIn">
        <h1 v-if="!loading">Stats for {{ feed.name}}</h1>      
        <h2 v-if="loading">loading {{ feedID }}</h2> 
    </div>
</template>
<script>
    export default {
        data: () => {
            return {
                feedID: false
            }
        },
        puted: {
            feed(){
                return this.$store.state.feed.currentFeed
            },
            loading(){
                return this.$store.state.feed.status.loading;
            }
        },
        created: function(){    
            this.feedID = this.$route.params.id;
            var fid = this.$route.params.id;
            const { dispatch } = this.$store;
            dispatch('feed/getFeed', {fid});
        }
    }
</script>

That dispatches 'feed/getFeed' from the feed module...

feed.module.js

import { feedStatsService } from '../_services';
import { router } from '../_helpers';

export const feed = {
    namespaced: true,
    actions: {
        getFeed({ dispatch, mit }, { fid }) {
            mit('FeedRequest', {fid});
            feedStatsService.getFeed(fid)
                .then(
                    feed => {
                        mit('FeedSuccess', feed);
                    },
                    error => {
                        mit('FeedFailure', error);
                        dispatch('alert/error', error, { root: true });
                    }
                )
        }
    },
    mutations: {
        FeedRequest(state, feed) {
            state.status = {loading: true};
            state.currentFeed = feed;
        },
        FeedSuccess(state, feed) {
            state.currentFeed = feed;
            state.status = {loading: false};
        },
        FeedFailure(state) {
            state.status = {};
            state.feed = null;
        }
    }
}

The feedStatsService.getFeed calls the service, which just runs a fetch and returns the results. Then mit('FeedSuccess', feed) gets called, which runs the mutation, which sets state.currentFeed=feed, and sets state.status.loading to false.

I can tell that it's stored, because the object shows up in the Vue dev tools. state.feed.currentFeed is the result from the service. But, my ponent doesn't change to reflect that. And there is a payload under mutations in the dev tool as well. When manually mit feed/feedSuccess in the dev tools, my ponent updates.

What am I missing here?

Share Improve this question asked Oct 18, 2018 at 1:18 madmad 1551 silver badge6 bronze badges 1
  • 1 It’s worth mentioning, you might want to look into Vuex Getters. With a getter, you can just map the getters as needed into your ponents instead of accessing state directly from a puted property. – user6434796 Commented Oct 31, 2018 at 4:34
Add a ment  | 

3 Answers 3

Reset to default 9

In the same way that ponent data properties need to be initialised, so too does your store's state. Vue cannot react to changes if it does not know about the initial data.

You appear to be missing something like...

state: {
  status: { loading: true },
  currentFeed: {}
}

Another option is to use Vue.set. See https://vuex.vuejs/guide/mutations.html#mutations-follow-vue-s-reactivity-rules...

Since a Vuex store's state is made reactive by Vue, when we mutate the state, Vue ponents observing the state will update automatically. This also means Vuex mutations are subject to the same reactivity caveats when working with plain Vue

Hey for all the people ing to this and not being able to find a solution. The following was what worked for me:

Declaring base state:

state: {
  mainNavData: [],
}

Then I had my action which is calling the now fixed mutation:

actions : {
  async fetchMainNavData({ mit }) {
    var response = await axios.get();
    mit('setMainNavData', response));
  },
  
};

Now my mutation is calling this updateState() function which is key to it all

mutations = {
  setMainNavData(state, navData) {
    updateState(state, 'mainNavData', navData);
  },
};

This is what the updateState function is doing which solved my issues.

const updateState = (state, key, value) => {
  const newState = state;
  newState[key] = value;
};

After adding updateState() my data reactively showed up in the frontend and I didn't have to manually mit the data in Vue tools anymore.

please note my store is in a different file, so its a little bit different.

Hope this helps others!

Sometimes updating property that are not directly in the state is the problem

{
   directprop: "noProblem",
   indirectParent: {
      "test": 5 // this one has a problem but works if we clone the whole object  indirectParent
   }
}

but it is a temporary solution, it should help you to force update the state and discover what is the real problem.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论