Vuex Getters 是否返回状态的引用数组、对象等?

问题描述

环境
我们有一个使用 Vue 2 的 Vue Cli。安装了 Vuex 和 TypeScript

问题
目前我们正在获取一些 vuex 状态数据(通过 vuex getter)。然后使用它。但是,如果我们改变“获得的数据”,它会影响 vuex 状态。好像疯了!这是一个非常愚蠢的服务模块精简版:

// 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
  }
}

非常精简的 getter 看起来像这样:

getTestStoreData(state) { return state.data }

所以上面 3 个中的 2 个会改变存储,因为它们改变了数据变量......这让我相信 getter 传递了状态数据的引用。

有人了解这个吗?或者知道处理它的好方法我有一些关于仅从商店传递嵌套数据的想法。这 stackoverflow answer 是我发现的一些最好的见解。

解决方法

在您的情况下,您需要克隆多维数组。 有两种类型的阵列克隆:浅和深。浅拷贝只覆盖数组的第一层,其余的都被引用。如果您想要嵌套数组的真实副本,则需要深度克隆。对于深度克隆,使用 JSON 方式或更好地使用 Lodash

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

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

要测试 Lodash clone 和 clonedeep 功能,您需要先安装 Lodash:

npm install --save lodash

yarn add lodash

现在安装了 lodash,现在使用 require() 函数来访问 Lodash 也提供的所有功能:

// 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 {
 .........