vue3搭配pinia报错怎么解决
本篇内容主要讲解“vue3搭配pinia报错怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue3搭配pinia报错怎么解决”吧!
An Object could not be cloned?
不知道有多少开发者遇到过这个报错——An Object could not be cloned
本人这里是一个electron项目,在使用ipcRenderer.invoke通讯时传入了一个对象,就抛出了这个错了。把传入的对象打印出来,发现对象里有字段被转成了proxy对象,估计就是在ipcRenderer.invoke处理proxy的时候无法处理,因此报错。
VUE 3的toRaw
我们都知道VUE 3 相比VUE 2在响应式数据的处理上有着巨大的改动,从2的Object.defineProperty到3的proxy。而为了让用户可以自行选择是否使用响应式,VUE 3提供了 reactive,ref等API。在把数据转成响应式之后,数据就已经被VUE修改成一个新的对象了,通过打印我们可以看到。
const obj = reactive({ a: 1, b: 2 });console.log(obj);
当然为了避免上述我遇到的这类问题,VUE 3提供了一个API让用户可以把proxy对象转回原生的对象。这个API就是toRaw()。
const obj = reactive({ a: 1, b: 2 });console.log(obj);console.log(toRaw(obj));
有了toRaw之后,理应不会遇到什么问题了。可是在我的场景里又有一个情况,就是混用了PINIA。
PINIA与VUE 3可以混合搭配?
PINIA是公认下一代的“VUEX”,同样有着与VUEX一样的特性——与VUE搭配使用会更加流程。但要注意的一点是,PINIA并不是VUE的专属,也就是说无论你开发的是什么项目,只要用到JavaScript你就可以用PINIA。也正因此如此,似乎与前面提到的一点是冲突的,这也出现在了我的项目中。
我们先来写一个简单的PINIA store
// store.jsexport const useCounterStore = defineStore('counter', { state: () => { return { myData: { o1: { b: 2 }, a: 1 } } }, actions: { setMyData(data) { this.myData = { ...data }; }, },})
然后在VUE中使用
import { useCounterStore } from "./stores/index.js";const counter = useCounterStore();const obj = reactive({ a: 1, b: 2 });console.log(counter.myData);counter.setMyData({newO:obj});console.log(counter.myData);
打印出来的结果如下:
我们发现这个myData对象是一个proxy嵌套proxy的对象。当我们想要让他转成原生对象时,在VUE 3项目中很自然会想到用toRaw。
console.log('toRaw',toRaw(counter.myData))
可是打印出来的结果是没有把里面的proxy解开的。
正因为这样所以我得到了本文最开始提到的报错信息。
同样的操作在VUE 3下的结果
遇到这样的问题,我第一时间怀疑是不是因为我在用到 setMyData中用到了解构语法。那如果同样的写法在VUE3 可行吗?我们再来试一下:
const obj = reactive({ a: 1, b: 2 });const obj2 = reactive({c:3,d:4});obj2.d = {...obj};console.log(obj2);
我们可以看到在VUE3中解构写法的赋值,并不会出现proxy嵌套的情况。说明VUE3在对自己的响应式数据赋值的时候是做了专门的处理的。因此我们可以得到一个简单的结论:PINIA与VUE3的搭配虽然在使用上可以很自然顺畅,但他们并不是天生一对的。PINIA在数据赋值的时候没有像VUE 3一样有针对VUE 3响应式数据的处理,同时VUE 3的toRaw也没有办法为PINIA的数据完美的还原。
最后的解决方式
说完了问题的原因,简单来提一下本文错误的解决方案。其实说到底我们的目标就是要得到一个“干净”的对象。我最后用是JSON.stringify()解决的,也说明了JSON.stringify的处理是可以解决proxy嵌套的。
console.log(counter.myData);console.log(JSON.stringify(counter.myData));
到此,相信大家对“vue3搭配pinia报错怎么解决”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341