Pinia新一代Vue状态管理库
Pinia新一代Vue状态管理库
Vapaus Qi简介
随着Vue2.x版本的停止更新维护,Vue3版本的迭代更新,新版本的相关生态也逐渐出现在大家的视野中。
其中,就包括Vue的新一代状态管理库 Pinia。
在Pina之前,我们一个复杂的应用通常是用Vuex来管理状态的,其中Vue2.x的版本对应的Vuex版本是Vuex3.x,而Vue3的版本对应的Vuex版本是Vuex4.x。
Pinia其实最初迭代的版本是Vuex5.x, 主要内容是设计及重构状态管理以适用于 Composition API,其设计原则跟思想与 Vuex 保持一致。所以最后将Pina作为新的推荐方案来代替Vuex。
Tips:
虽然Pina开始是要适用于Composition API,但作者初心也是同时支撑Vue2.x和Vue3.x,所以无论你的Vue是哪个版本都可以愉快的使用Pinia。
为什么要使用Pinia
在Vue3中,我们通常用ref或reactive来定义数据,所以会有同学说,我用如下方法定义并共享全局数据也可以做到状态管理:
1 | export const state = reactive({}) |
诚然,这种方式在单页面应用也可以实现状态管理,但如果你的应用使用了SSR(服务端渲染,后续会出一期文章单独讲一下),那可能会存在相关的安全问题,此外,Pinia还有其他的优势:
测试工具集
插件:可通过插件扩展 Pinia 功能
为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能
支持服务端渲染
Devtools 支持(超级好用)
- 追踪 actions、mutations 的时间线
- 在组件中展示它们所用到的 Store
- 让调试更容易的 Time travel
热更新
- 不必重载页面即可修改 Store
- 开发时可保持当前的 State
Pinia主要构成
- Store: 用于存储应用的状态,类似于Vuex中的state。
- Action: 用于业务逻辑,类似于Vuex中的action。
- Getter: 用于获取应用的状态,类似于Vuex中的getter。
- Plugins: Pinia 插件。
Pinia与Vuex区别
1、 移除 mutations: 在 Vuex 中,状态的改变必须通过提交 mutations 实现,而 mutations 只能执行同步操作。为了支持异步数据操作,Vuex 引入了 actions,通过 actions 来调用 mutations 修改数据。在 Pinia 中,actions 既支持同步操作也支持异步操作,因此 mutations 显得有些冗余,因而被移除了。这简化了状态管理的逻辑,减少了不必要的复杂性。
2、对 TypeScript 的支持更为友好: 使用 Pinia 时,不再需要定义复杂的封装器来支持 TypeScript。Pinia 直接内置了对 TypeScript 的良好支持,提供了更自然的类型推断和安全性,使得开发体验更加顺畅。
3、避免了魔法字符串: 在使用 Vuex 时,我们经常会看到类似 this.$store.commit(“xxxxx”) 这样的魔法字符串。尽管可以将这些字符串提取为常量进行维护,但这依然不够便捷。在 Pinia 中,这种方式被优化了。我们可以直接调用 defineStore 后暴露出来的方法,通过 $patch、actions 的方式,或是直接修改 store 中的值,这样避免了魔法字符串的使用,提高了代码的可读性和维护性。
4、动态的 stores: Pinia 支持随时定义 stores,它们默认是动态的。这意味着开发者可以在需要时灵活地创建和使用 stores,不再需要像 Vuex 那样繁琐地进行动态添加。
5、简化了模块管理: 在 Pinia 中,不再需要嵌套结构的模块。这与 Vuex 的模块化结构不同,在 Vuex 中我们经常需要嵌套命名空间模块来组织状态。在 Pinia 中,模块化被简化了,我们可以用更简洁的方式来管理应用的状态,省去了复杂的模块嵌套和命名空间的配置。
实际体验
接下来,我们通过一个简单的示例来体验一下Pina。
1、项目搭建
前提:使用vite搭建基础的vue3项目来进行演示。(此步骤不多赘述,可自行查阅资料)。
2、安装pina
1 | //src/main.js |
3、创建 store
1 | //src/store/index.js |
在这个文件里我们定义了一个 testStore,其中包含age,name两个属性以及一个increment方法供我们后续使用。
注意: defineStore接收两个参数,第一个参数是store的唯一标识(上述代码中用两种方式定义了同一个唯一标识进行了演示,实际使用中要要注释调其中一种),第二个参数接收Setup 函数或 Option 对象(上述代码已做了演示),Setup 函数更适配Vue3.x的书写规范,如果你是Vue2.x的项目或者个人书写风格觉得选项式看着更清晰一些,可以选择Option Store形式的书写规范。
4、使用 store
1 | <script setup> |
在上述代码中,我们定义了testData来接收store,并在页面中将姓名和年龄都展示出来,并且点击增加年龄按钮的时候,页面数据也能实时获取到store中的最新值。接下老让我们看下页面及VueTools中的对应状态变化情况:
如果,开发者觉得上述使用testData一直访问属性太过繁琐,我们还可以使用解构的形式来获取,接下来我们改造上述代码
1 | <script setup> |
注意:
1、解构后会使数据失去响应式,所以我们要使用storeToRefs,将解构的数据重新变成响应式。
2、storeToRefs 会将 Pinia store 的属性转换为 refs,使得它们可以被 Vue 的响应式系统检测到变化。然而,storeToRefs 只对 state 进行转换,不包括 actions,所以increment 方法要单独解构并且不能使用storeToRefs包裹。
接下来我们看一下实现效果:
可以看到数据状态及方法还是正常的。
5、修改store中值的几种方法
1 | <script setup> |
6、Pinia的插件
Pinia插件支撑了Pinia的扩展,它允许你添加全局状态、修改状态、添加全局方法等。支持一下等功能:
为 store 添加新的属性
定义 store 时增加新的选项
为 store 增加新的方法
包装现有的方法
改变甚至取消 action
实现副作用,如本地存储
仅应用插件于特定 store
更多插件的功能请查看官方的插件文档
结语
以上就是对pinia的介绍及使用,相信大家已经对pinia有了一个基本的了解,如果有不对的地方也希望大家指正。