Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
343 views
in Technique[技术] by (71.8m points)

javascript - Do Vuex Getters return a reference (array, object, whatever) to the state?

Environment
We have a Vue Cli using Vue 2. Vuex and TypeScript are installed

Issue
Currently we're getting some vuex state data (via a vuex getter). Then working with it. However, if we mutate the "gotten data" it affects the vuex state. It seems crazy! Here's a very silly stripped down version of a services module:

// vuex
import { mapState } from 'vuex'
// store
import store from './../store';
// types
import { ServiceType } from './../types/services'

export default class TestService implements ServiceType {

  serviceFunction(someArray: Array<number>) {

    // this will return some nested/multidimensional data:
    // [
    //   { prop: [[1, 2, 3, 4]] }
    // ]
    let data = store.getters['getTestStoreData'] 
      
      data[0].prop[0] = someArray          // doesn't mutate the state 
      data[0].prop = [someArray]           // mutates the state
      data[0].prop.splice(0, 1, someArray) // mutates the state
  }
}

The very very stripped down getter looks something like this:

getTestStoreData(state) { return state.data }

So 2 of the 3 above will mutate the store, since they mutate the data variable... Which leads me to believe the getter passes a reference of the state data.

Anyone have insight into this? Or know a good way to handle it? I've got some ideas about passing just the nested data from the store. This stackoverflow answer is some of the best insight I've found.

question from:https://stackoverflow.com/questions/65944942/do-vuex-getters-return-a-reference-array-object-whatever-to-the-state

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In your case you need to clone the multidimensional array. There are 2 types of array cloning: shallow & deep. Shallow copies only cover the 1st level of the array and the rest are referenced. If you want a true copy of nested arrays, you’ll need a deep clone. For deep clones, go with the JSON way OR better yet use Lodash

// Using JavaScript
let data = JSON.parse(JSON.stringify(store.getters['getTestStoreData']));

Or

// Using Lodash
let data = _.cloneDeep(store.getters['getTestStoreData']);

To test out the Lodash clone and clonedeep functions, you will need to install Lodash first:

npm install --save lodash

Or

yarn add lodash

With lodash now installed, use the require() function to now access all the functions that Lodash has too offer:

// vuex
import { mapState } from 'vuex'
// store
import store from './../store';
// types
import { ServiceType } from './../types/services'

const _ = require('lodash'); // Line to be included

export default class TestService implements ServiceType {
 .........

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...