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

Posted

技术标签:

【中文标题】Vuex Getters 是不是返回对状态的引用(数组、对象等)?【英文标题】:Do Vuex Getters return a reference (array, object, whatever) to the state?Vuex Getters 是否返回对状态的引用(数组、对象等)? 【发布时间】:2021-05-02 19:26:52 【问题描述】:

环境 我们有一个使用 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
  

非常精简的吸气剂看起来像这样:

getTestStoreData(state)  return state.data 

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

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

【问题讨论】:

【参考方案1】:

在您的情况下,您需要克隆多维数组。 数组克隆有 2 种类型:浅层和深层。浅拷贝仅覆盖数组的第一级,其余的被引用。如果您想要嵌套数组的真实副本,则需要深度克隆。对于深度克隆,使用 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 
 .........

【讨论】:

谢谢!这实际上是我们现有的解决方案,但每次都复制完整的数据似乎非常密集。所以我们将编写存储操作来拼接/复制我们需要更改的内容并将其传递给服务。令我惊讶的是,getter 本身并没有返回副本。

以上是关于Vuex Getters 是不是返回对状态的引用(数组、对象等)?的主要内容,如果未能解决你的问题,请参考以下文章

getters 在 vuex 中总是返回 true

Vue全家桶Vuex状态管理

vuex状态管理

状态渲染前的 Vue.js/vuex getters 错误

vuex简单整理

vuex使用前与使用后的写法---getters(获取事件)