pinia 踩坑总结

简介: pinia 踩坑总结

网络异常,图片无法展示
|


最近在做项目调优,一个 Vue3 项目当初使用 vuex 做的状态管理,最近大家都在谈 pinia,看了一下文档,它的使用方法更贴近于 Composition API,对 TypeScript 也更友好,写法上也更简洁,emmm...,香啊!


网络异常,图片无法展示
|


这必须安排啊,于是我开始用 pinia 替换 vuex。


  1. store 文件夹下的所有文件重构
  2. 项目中所有基于 vuex 的状态替换为基于 pinia 的状态


= 获取状态响应式丢失


然后遇到第一个问题,如果要获取某个状态,并进行一些操作,最好不要这么写


import { useSettingStore } from "@/store/setting";
const settingStore = useSettingStore();
const isCollapse = settingStore.isCollapse;
const changeCollapse = () => {
  settingStore.isCollapse = !isCollapse;
};
复制代码


这样直接 const isCollapse = settingStore.isCollapse; 通过 = 赋值拿到的状态是没有响应式的,正确的方式是通过 storeToRefs 进行解构获取,修改后代码如下:


import { storeToRefs } from "pinia";
import { useSettingStore } from "@/store/setting";
const settingStore = useSettingStore();
const { isCollapse } = storeToRefs(settingStore);
const changeCollapse = () => {
  settingStore.setCollapse(!isCollapse.value);
};
复制代码


ps: 修改状态的时候最好还是通过 action 来做。


cdn 加载 Vue 线上环境 pinia 响应式丢失


这个坑真的是如果思路不对,要被坑死。


为了项目更快的加载,我配置了 external 通过 cdn 加载 VueElementPlus,这里也说一下配置过程,方便需要的小伙伴。


// vite.config.js
import { viteExternalsPlugin } from "vite-plugin-externals";
plugins: [
    // external cdn 引入依赖包
    viteExternalsPlugin(
        {
          vue: "Vue",
          "element-plus": "ElementPlus",
        }
    )
]
复制代码


// index.html
<head>
    <meta ...
    <!-- 导入 Vue 3 -->
    <script src="//unpkg.com/vue@next"></script>
    <!-- 导入样式 -->
    <link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css" />
    <!-- 导入组件库 -->
    <script src="//unpkg.com/element-plus"></script>
    <title>...
<head>
复制代码


这样就完成了,这里用到了 vite-plugin-externals 插件,记得要安装一下。


到了这里,一切都很美好,打包上线吧!


项目部署之后,随便点一点测试下,然后发现当我点击这个按钮控制侧边栏展开收起的时候,


网络异常,图片无法展示
|

网络异常,图片无法展示
|


没有作用?!打开本地服务,点击,比德芙还丝滑好不好!那么问题就出在了线上环境和本地服务的差异。


因为线上环境每次都需要部署,比较麻烦(我是在个人服务器上部署了一套测试,所以不影响真实的线上环境),同时为了对比是不是线上环境的问题(Linux 服务器以及 nginx 配置),我在登录页面获取了 isCollapse 并尝试进行操作,同样,本地服务没有问题,打包,开启 Live Serve,发现本地环境操作也不行,那么就可以确定是打包后的文件出了问题。


因为我项目配置了 cdn 加载 Vue,所以自然想到了这个问题,把 cdn 加载干掉,再次打包,开启 Live Serve,发现本地环境可以了。


到了这里,可以确定配置 cdn 加载后,造成了这个问题。因为实际项目依赖和模块比较多,为了排除干扰,调试更方便,我开了一个新的测试项目(我是之前就有这么一个专门用来测试问题的项目,用来复现和调试实际项目中的问题),首先把 Vue ElementPlus pinia 都搞好,不开启 cdn 加载,本地服务和打包后的本地环境都是 OK 的,然后开启 cdn 加载,本地服务 OK,打包后本地环境 pinia 响应式失效,完美复现。


接下来就是排查具体原因,有两个点:


  1. vite-plugin-externals
  2. pinia


查看 vite-plugin-externalsREADME 可以看到,它只是把依赖库的引入转为 window 下的全局变量,


// 选项
viteExternalsPlugin({
  vue: 'Vue',
}),
// 源代码
import Vue from 'vue'
// 转换后
const Vue = window['Vue']
复制代码


并没有其他什么操作,所以我感觉不是它的问题,排除嫌疑。


那么就剩下 pinia 了,这个时候我打开打包后的 vendor.js 发现里面还是有 Vue 的代码。


网络异常,图片无法展示
|


vue hack 数组


然后我去看了下 pinia 的源码,发现它依赖了 vue-demi 这个库,而 vue-demi 这个库又依赖了 Vue ,而我们配置 external 的插件 vite-plugin-externals 默认是不处理 node_modules 下面的包的,所以我们使用的 Vue 实例和 pinia 绑定的 Vue 实例不是一个实例,所以我们操作 pinia 中的状态在项目中表现为没有响应。


所幸 vite-plugin-externals 提供配置,可以帮我们处理 node_modules 下面的包,所以修改配置如下:


// vite.config.js
import { viteExternalsPlugin } from "vite-plugin-externals";
plugins: [
    // external cdn 引入依赖包
    viteExternalsPlugin(
        {
          vue: "Vue",
          "element-plus": "ElementPlus",
        },
        {
          filter(code, id) {
            // 处理 pinia,解决 cdn 加载 Vue 响应式丢失问题
            if (id.includes("pinia")) {
              return true;
            }
            return false;
          },
        }
]
复制代码


这样 vite-plugin-externals 就会帮我们把 pinia 中依赖的 Vue 也处理成 window['Vue']


再次打包测试,本地环境以及部署线上环境就都 OK 了!


网络异常,图片无法展示
|


2022.3.13 更新

今天搭建新的开发框架遇到一个问题,vite-plugin-externals 之前我用的是 0.0.93 版本,这两天发布了 1.0.9 版本,今天默认安装也是这个版本,结果出现页面刷新后,再操作 pinia 状态,部分状态缓存失败问题,已提 issues,如果大家使用 1.0.0 版本出现问题,可以尝试使用 0.0.93 版本。


如有任何问题或建议,欢迎留言讨论!

相关文章
|
5月前
|
存储 缓存 JavaScript
10 个简单但不能不会的 Vue 面试问答
10 个简单但不能不会的 Vue 面试问答
|
8月前
|
存储 缓存 JavaScript
谈谈你对vue的了解
谈谈你对vue的了解
57 3
|
缓存
Vue3案例-todoMVC-pinia版 (可跟做练手)
Vue3案例-todoMVC-pinia版 (可跟做练手)
59 0
|
8月前
|
前端开发 JavaScript 中间件
Vue3整合VxeTable,2024大厂前端面试
Vue3整合VxeTable,2024大厂前端面试
|
8月前
|
JavaScript 前端开发 API
vue面试题目汇总
vue面试题目汇总
100 4
|
8月前
|
JavaScript
Vue 学习记录,从难受到真香
Vue 学习记录,从难受到真香
46 2
|
8月前
|
JavaScript 前端开发 算法
前端常见的Vue面试题目汇总
前端常见的Vue面试题目汇总
107 0
|
前端开发 API
react踩坑
react踩坑
259 0
vue3学习记录(1)
随着vue3的普及我们团队开始全面接纳了vue3。
1062 154
vue3学习记录(2)
随着vue3的普及我们团队开始全面接纳了vue3。
1137 177

热门文章

最新文章