Reputation: 2978
I have this state storeMovement
and a mutation to update this state updateStoreMovement
I'm loading this state in my vue component with mapState
, and accessing it through the methods with this.storeMovement
What I want to know is, what can go wrong if I update an specifc property of this state without using the mutation, something like this
this.storeMovement.steps = new_steps
this propagates to all the others components without needing to create a mutations just to update this property
Will this give me trouble later?
Upvotes: 0
Views: 1040
Reputation: 29132
There are several different angles here.
An object in your store state
will be reactive, just the same as in component data
. Reading properties of that object will be tracked and writing new values will trigger dependencies. This is just the Vue reactivity system doing its thing. The store isn't really involved from a reactivity perspective.
So, as you've observed, you can update properties of your reactive object and everything seems to update just fine.
You get a similar phenomenon with props. Child components shouldn't change prop values, there's a warning message if they try. But if the prop value is a reactive object then the properties of that object can be changed and everything appears to work fine.
So what's the problem?
There's a guiding principle that applies in both of these cases. Data should only be updated by its owner. In the store case the owner is the store, or a store module. For props the owner is the upstream component that passed the data down.
Why?
It is easier to maintain if only the owner changes the data. If that responsibility is spread across multiple places it is more difficult to debug or change in future. In particular, finding all usages of a store mutation is usually pretty easy, whereas trying to find everywhere that updates a property with a common name, like name
, can be pretty difficult.
Further, there is an assumption that the object is the 'root' data here. What if you later decide that this object should be created in a computed property or a store getter instead of being directly in data/state? Suddenly it isn't a reactive object and changing the property won't work. Instead you need to update some other, underlying property that is used to generate the object. This is easier if all update logic is in the owner.
There are some other benefits specific to the store.
While the store doesn't get involved directly in the reactivity it does have a subscribe
method that can be used by plugins to track when mutations are called:
https://vuex.vuejs.org/api/#subscribe
Any plugins using these events won't be notified if you don't go through a mutation. If, for example, you're using a plugin to persist state to localStorage
then data changes outside of mutations won't be persisted, at least not immediately. If the page refreshes then the state loaded from localStorage
will be out-of-date.
In the same vein, Vue DevTools has support for something called time-travel debugging. This will only work properly if you use mutations.
If you aren't already familiar with it, I suggest taking a look at strict mode:
https://vuex.vuejs.org/guide/strict.html
I would finish by noting that the store is very often misused and I personally believe that the design of the Vuex store must shoulder some of the blame for that. I believe what I've outlined above is somewhere close to the 'official' line but, in my opinion, it is tantamount to describing best practices for using a chocolate fireguard.
Upvotes: 4