简体   繁体   中英

Vuejs Vuex state overrides outside store without mutation or direct access to state

State of Vuex overrides in the map()

Expecting beahavior - count always 1 when click to the Trigger button

Current behavior is count is encreasing each time when click to the Trigger button and if we take a look on a console log we can see that getter returns mutated state

 const store = new Vuex.Store({ state: { stuff: [{ count: 0 }] }, mutations: {}, getters: { stuff: s => s.stuff, } }) new Vue({ el: '#vue', store, data() { return { res: [] } }, methods: { trigger() { const stuff = this.$store.getters.stuff console.log(stuff) const res = stuff.map(p => { p.count += 1 return {...p } }) this.res = res } }, })
 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script src="https://unpkg.com/vuex@3.6.2/dist/vuex.js"></script> <div id="vue"> <div> <button @click=trigger()>Trigger</button> <pre>{{res}}</pre> </div> </div>

This is expected. Vuex is just a library inside JS virtual machine - the rules of JS applies...

Value vs. Reference

  1. const stuff = this.$store.getters.stuff - stuff is now a reference to an existing object (array in this case)
  2. stuff.map() iterates the array passing each item as p parameter. If the p is an Object, p is the reference to an object inside Vuex - if you modify it, you are modifying the object inside the Vuex store

This is bad and to be sure and safe, you can set Vuex to throw an error anytime data inside Vuex are modified without using mutation

const store = new Vuex.Store({
  // ...
  strict: process.env.NODE_ENV !== 'production'
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM