【问题标题】:How to fix a vuex mutation warning with a .slice'd array如何使用 .slice'd 数组修复 vuex 突变警告
【发布时间】:2021-12-18 01:51:12
【问题描述】:

我被这个错误弄疯了

[vuex] 不要在突变处理程序之外改变 vuex 存储状态

我有一个异步 vue/nuxt 方法,当用户想要编辑他/她的帖子时会触发该方法。我正在使用 vuex 的商店与我的 API 建立链接。
我在用户执行操作时使用组件数据来保存内容更改,这是一种基本配置。

当我尝试对媒体进行排序时出现错误。
无论我多么努力地尝试破坏引用,vue 都会不断向我大喊“不要改变外部处理程序”的错误。

代码如下:

async editSouvenir(id, data) {
  try {
    this.isLoading = true;
    if (this.filesToAdd) {
      for (let file of this.filesToAdd) {
        await this.$store.dispatch('media/CREATE_MEDIA', {
          souvenirId: id,
          file,
        });
        this.fileCtn++;
      }
    }

    if (data.mediaTab.length > 0) {
      let newOrder = 1;
      const newMediaTab = this.newMediaTab;
      // browsing media list
      const newArray = data.mediaTab.slice().sort((a, b) => {
        return newMediaTab.indexOf(a) - newMediaTab.indexOf(b);
      });

      // updating order
      for (let i = 0; i < newArray.length; i++) {
        newArray[i].order = i + 1;
      }

      // saving media data
      data.mediaTab = newArray;
      console.log(data.mediaTab);
    }

    this.isLoading = false;
    if (
      !this.createSouvenirError &&
      !this.createMediaError &&
      !this.postMediaError
    ) {
      await this.$store.dispatch('souvenir/EDIT', { id, data });
      this.$router.push({
        path: '/pns-editor',
        query: { selectedYear: data.date.substr(0, 4), souvenir: id },
      });
    } else {
      // @todo gérer l'erreur
    }
  } catch (err) {
    console.log(err);
    // this.isLoading = false;
  }
},

vuex mutating 错误是由这一行触发的:

newArray[i].order = i + 1;

我要编辑的数组是帖子对象中的媒体对象数组。

{ 
    id: 1235354,
    title: 'my title',
    mediaTab: [{
       ** my array of objects **
    }]
}

我不明白我在哪里改变存储状态数据。我已经阅读了几个关于 vuex 变异错误的答案,但我无法将它们与我的案例相匹配。

【问题讨论】:

标签: vuejs2 nuxt.js


【解决方案1】:

.slice 只为您的数组创建一个shallow copy,因此由于您正在更深入地访问它,因此它会抱怨突变,因为您仍然针对下面的参考 1 级。

一个解决方案是

<script>
import { cloneDeep } from 'lodash-es'

...
const newArray = cloneDeep(data.mediaTab)

它可能不像mentioned here 那样有奇怪的行为,因为它是lodash,你可以完全导入它并知道它已经过优化。
只是不要导入整个库,而只导入有用的方法,因此为什么要destructuring + lodash-es。

PS:要小心,因为.sort also mutates 是一个数组。

【讨论】:

  • 谢谢,我很生气唯一的解决方案是使用 lodash,但如果每个人都在使用它,我认为这是正确的做法 :) 我会小心的。 :)
  • @fxguillois 这不是唯一的解决方案,而是 99% 防弹且高效的解决方案。此外,如果您通过 tree-shaking 仅导入所需的方法(如我的代码 sn-p 所示),这个库经过了超级实战测试和轻量级。
  • 就像一个魅力。抱歉耽搁了,我在添加 lodash 后遇到了一个 docker 错误。
  • 我说得太快了。 lodash-es 似乎与 nuxt 不兼容。我尝试了 transpile 选项,但杀死了页面中的羽毛笔和其他代码。现在尝试npmjs.com/package/lodash.clonedeep,但码头工人让我很痛苦。我会告诉你什么时候修好。我昨天在另一个站点(没有docker)中使用了你的答案,我没有缺点。奇怪。
  • @fxguillois lodash 正常兼容。只需安装lodash-es。
猜你喜欢
  • 2018-09-12
  • 1970-01-01
  • 2019-08-08
  • 2020-11-28
  • 2017-10-25
  • 2017-07-03
  • 1970-01-01
  • 2021-03-29
  • 2019-12-07
相关资源
最近更新 更多