vue3搭配pinia的踩坑实战记录

 更新时间:2022年04月11日 10:32:28   作者:bluesGavin  
Pinia是一个同时支持Vue2和Vue3的应用状态管理工具,简单来说就是为了管理整个应用中的响应式数据,解决各个组件交互时数据状态的不好管理的问题,下面这篇文章主要给大家介绍了关于vue3搭配pinia踩坑的相关资料,需要的朋友可以参考下

前言

最近接手了一个新项目,用的是VUE3+pinia的组合。由于之前没有用过这2个库,只能现学现做。幸运的是这两者的上手难度都不大,项目可以正常开发。但这其中也遇到了一些坑,今天就来讲其中我印象最深的一个。

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.js
export 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));

当然我的同事用lodash的omit方法也可以解决,只是我觉得JSON.stringify会更加的“原生”。关于lodash的omit更多信息可以看:www.lodashjs.com/docs/lodash…

总结

相信并不是很多人会遇到我的这种情况,我也知道手上的项目代码中有很多可以优化的地方(我是中途加入这个项目的)。但本文想要分享的是在VUE 3搭配PINIA做项目开发的时候,有可能会遇到的问题。以及表明他们两并不是“天生一对”的,当然对于这个问题不知道后续会不会被优化。我个人是觉得如果把他们看作是两个独立的工具,其实这个并不是BUG,更多的是开发者的“一厢情愿”。

最后,希望本文可以帮助到一些开发者,在开发过程中避免掉坑。

到此这篇关于vue3搭配pinia踩坑的文章就介绍到这了,更多相关vue3 pinia踩坑内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue+WebSocket页面实时刷新长连接的实现

    Vue+WebSocket页面实时刷新长连接的实现

    最近vue项目要做数据实时刷新,数据较大,会出现卡死情况,所以本文主要介绍了页面实时刷新长连接,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • vue下载blob文档流实现过程

    vue下载blob文档流实现过程

    文章介绍了两种在Vue中下载Blob文档流的常见方法:一种是通过创建a标签并触发点击事件来下载,另一种是使用`file-saver`库和封装的`download.js`公用方法来处理文档流的下载
    2025-12-12
  • 解决VUE-npm ERR! C:\rj\node-v14.4.0-win-x64\nod问题

    解决VUE-npm ERR! C:\rj\node-v14.4.0-win-x64\nod问题

    这篇文章主要介绍了解决VUE-npm ERR! C:\rj\node-v14.4.0-win-x64\nod问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • VUE 使用canvas绘制管线管廊示例详解

    VUE 使用canvas绘制管线管廊示例详解

    这篇文章主要为大家介绍了VUE 使用canvas绘制管线/管廊实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • vue-cli-service的参数配置过程

    vue-cli-service的参数配置过程

    这篇文章主要介绍了vue-cli-service的参数配置过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • element el-table如何实现表格动态增加/删除/编辑表格行(带校验规则)

    element el-table如何实现表格动态增加/删除/编辑表格行(带校验规则)

    这篇文章主要介绍了element el-table如何实现表格动态增加/删除/编辑表格行(带校验规则),本篇文章记录el-table增加一行可编辑的数据列,进行增删改,感兴趣的朋友跟随小编一起看看吧
    2024-07-07
  • vue 自定义全局方法,在组件里面的使用介绍

    vue 自定义全局方法,在组件里面的使用介绍

    下面小编就为大家介绍一下vue 自定义全局方法,在组件里面的使用。具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • 基于Vue实现人民币小写转为大写功能

    基于Vue实现人民币小写转为大写功能

    在金融类应用中,经常需要将金额从小写数字转换为大写形式,这种转换主要用于正式票据、合同等场合,以增加文本的专业性和可读性,本文将详细介绍如何在Vue.js项目中实现这一功能,并提供多个示例和详细的代码说明,需要的朋友可以参考下
    2024-09-09
  • mpvue性能优化实战技巧(小结)

    mpvue性能优化实战技巧(小结)

    这篇文章主要介绍了mpvue性能优化实战技巧(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • vue中数据绑定值(字符串拼接)的几种实现方法

    vue中数据绑定值(字符串拼接)的几种实现方法

    这篇文章主要介绍了vue中数据绑定值(字符串拼接)的几种实现方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07

最新评论