如何使用 .slice'd 数组修复 vuex 突变警告
Posted
技术标签:
【中文标题】如何使用 .slice\'d 数组修复 vuex 突变警告【英文标题】: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 变异错误的答案,但我无法将它们与我的案例相匹配。
【问题讨论】:
这能回答你的问题吗? Vuex - Do not mutate vuex store state outside mutation handlers 另外,这篇文章可能是个好读物:flaviocopes.com/how-to-clone-javascript-object 【参考方案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
。以上是关于如何使用 .slice'd 数组修复 vuex 突变警告的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 localStorage 修复 Vuex 中的 JSON 解析错误