Vuex报错:排序数组时触发“请勿在mutation外修改状态”错误
解决Vuex状态修改错误:sort操作"局部变量"却触发报错的问题
嘿,我一眼就看出问题出在哪了——你以为purposeArrayZ是完全独立的局部变量,但实际上它只是Vuex store中状态数组的一个引用!数组是引用类型,所以你对它做的sort操作直接修改了原数组(也就是Vuex的state),这就触发了Vuex的规则警告:只能在mutation handlers里修改状态。
为什么会出错?
先看你的代码里的关键部分:
function firePixels (clientId, result) { return new Promise((resolve, reject) => { const purposesZ = [1,2,3,4,5]; let purposeArrayZ = cmp.getPurposesAllowed(); // 这里拿到的是Vuex state数组的引用 purposeArrayZ.sort((a, b) => a - b); // sort是原地修改方法,直接改了Vuex的state! if(isEqual(purposesZ,purposeArrayZ)){ console.log("equal!"); resolve(console.log("equal!")); } }); }
sort()方法是原地排序,会直接修改调用它的数组本身。而cmp.getPurposesAllowed()返回的并不是一个新数组,而是指向Vuex store中某个状态数组的指针。所以你以为在操作局部变量,实则在偷偷修改Vuex的state,这当然会报错。
怎么修复?
核心思路就是:先创建原数组的副本,再对副本进行排序,这样就不会影响到Vuex的原始状态了。给你几种简单的实现方式:
方法1:用slice()创建副本
slice()不带参数时会返回原数组的浅拷贝,生成一个新数组:
let purposeArrayZ = cmp.getPurposesAllowed().slice(); purposeArrayZ.sort((a, b) => a - b);
方法2:用扩展运算符...快速拷贝
ES6的扩展运算符可以轻松创建数组副本,写法更简洁:
let purposeArrayZ = [...cmp.getPurposesAllowed()]; purposeArrayZ.sort((a, b) => a - b);
方法3:用Array.from()生成新数组
Array.from()也可以将现有数组转换成一个新数组:
let purposeArrayZ = Array.from(cmp.getPurposesAllowed()); purposeArrayZ.sort((a, b) => a - b);
另外提个小细节:你代码里的resolve(console.log("equal!"))其实会把undefined作为Promise的结果返回(因为console.log没有返回值),如果需要传递有效结果的话,可以改成resolve("equal!")哦。
内容的提问来源于stack exchange,提问作者dendog
相关产品推荐
相关产品推荐

