Pinia快速入门-上手指南

Pinia是什么 PiniaVue 的存储库,允许您跨组件/页面共享状态。Pinia 这款产品最初是为了探索 Vuex 的下一个版本,整合了核心团队关于 Vuex 5 的许多想法。最终,我们意识到 Pinia 已经实现了我们想要在 Vuex 5 中提供的大部分内容,因此决定将其作为 新的官方推荐
Pinia特点

  • 足够轻量,Pinia 重约 1kb,甚至会忘记它的存在!
  • 去除 MutationActions 支持同步和异步(Actions一个顶俩,写起来简洁);
  • 无需手动注册 Store,Store 仅需要时才自动注册。如果从不使用,则永远不会“注册”(省心);
  • 没有模块嵌套,只有 Store 的概念,Store 之间可以自由使用,更好的代码分割;
  • Vue2Vue3 都能支持;
  • 支持大型项目迁移期间,PiniaVuex 混合使用(贴心迁移);
  • 更完美的 typescript 的支持;
  • Vue devtools 挂钩,Vue2 和 Vue3 开发体验更好;
  • 支持插件扩展功能;
  • 支持模块热更新,无需加载页面可以修改容器,可以保持任何现有的状态;
  • 支持服务端渲染;
VuexPinia 用哪个 Vuex 现在处于维护模式。它仍然可以工作,但不再添加新的功能。对于新的应用项目,建议使用 PiniaPinia 已经实现了我们想要在 Vuex 5 中提供的大部分内容,因此决定将其作为 新的官方推荐(注意:旧版网站没有更新)
Pinia快速入门-上手指南
文章图片

如何使用 Pinia 一、安装
npm install pinia

二、定义 Store
新建 src/stores 目录并在其下面创建 index.ts
Pinia 的目录通常被称为 stores 而不是 store, 这是为了强调 Pinia 使用多个 store,而不是 Vuex 中的单个 store,同时也有迁移期间 PiniaVuex 混合使用的考虑。
// src/stores/index.ts // 引入Store定义函数 import { defineStore } from 'pinia'// 定义Store实例并导出,useStore可以是任何东西,比如useUser, useCart // 第一个参数,唯一不可重复,字符串类型,作为仓库ID 以区分仓库 // 第二个参数,以对象形式配置仓库的state,getters,actions export const useStore = defineStore('main', { // state 推荐箭头函数,为了TS类型推断 state: () => { return { name: '张三', counter: 0 } }, getters: {}, actions: {} })

在 main.ts 中引入并挂载到根实例
// src/main.ts import { createApp } from 'vue' import App from './App.vue' import { createPinia } from 'pinia' // 创建Vue应用实例 // 实例化 Pinia // 以插件形式挂载Pinia实例 createApp(App).use(createPinia()).mount('#app')

三、State
1、访问State

2、修改State 1、单个参数修改 state
store.counter++

2、多个参数修改 state
store.$patch({ counter: store.counter + 1, name: 'Abalam', })

3、全部修改 state
store.$state = { counter: 666, name: 'Paimon' } 或 pinia.state.value = https://www.it610.com/article/{}

3、重置State 将状态重置为初始值
const store = useStore() store.$reset()

4、vue2写法
import { mapState } from 'pinia' import { useCounterStore } from '../stores/counterStore'export default { computed: { ...mapState(useCounterStore, ['counter']) // 或 ...mapState(useCounterStore, { myOwnName: 'counter', double: store => store.counter * 2, magicValue(store) { return store.someGetter + this.counter + this.double }, }), }, }

四、Getters
getter 中的值有缓存特性,类似于computed,如果值没有改变,多次使用也只会调用一次
1、定义Getters
export const useStore = defineStore('main', { state: () => ({ counter: 0, }), getters: { doubleCount: (state) => state.counter * 2, // 自动推导返回类型 doubleCount(state) { return state.counter * 2 }, // 依赖getters返回参数,则需要显性的设置返回类型 doublePlusOne(): number { return this.doubleCount + 1 }, }, })

2、使用Getters

3、vue2写法
import { mapState } from 'pinia' import { useCounterStore } from '../stores/counterStore'export default { computed: { ...mapState(useCounterStore, ['doubleCount']) // 或 ...mapState(useCounterStore, { myOwnName: 'doubleCounter', double: store => store.doubleCount, }), }, }

五、Actions
Pinia 中删除了 MutationActions 支持同步和异步
1、定义 Actions
// 同步 export const useStore = defineStore('main', { state: () => ({ counter: 0, userData: null, }), actions: { increment() { this.counter++ }, randomizeCounter() { this.counter = Math.round(100 * Math.random()) }, }, })

// 异步 import { mande } from 'mande' const api = mande('/api/users')export const useUsers = defineStore('users', { state: () => ({ userData: null, }),actions: { async registerUser(login, password) { this.userData = https://www.it610.com/article/await api.post({ login, password }) }, }, })

2、调用 Actions 1、可以直接调用 store 的任何方法

2、action 间的相互调用,直接用 this 访问即可。
export const useUserStore = defineStore({'user', actions: { increment() { this.counter++ }, increase() { // 调用另一个 action 的方法 this.increment() }, } })

3、在 action 里调用其他 store 里的 action 也比较简单,引入对应的 store 后即可访问其内部的方法。
import { useAuthStore } from './auth-store'export const useSettingsStore = defineStore('settings', { state: () => ({ preferences: null, }), actions: { async fetchUserPreferences() { // 调用 auth-store store 里的 action 方法 const auth = useAuthStore() if (auth.isAuthenticated) { this.preferences = await fetchPreferences() } else { throw new Error('User must be authenticated') } }, }, })

3、vue2写法
import { mapActions } from 'pinia' import { useCounterStore } from '../stores/counterStore'export default { methods: { ...mapActions(useCounterStore, ['increment']) // 或 ...mapActions(useCounterStore, { myOwnName: 'doubleCounter' }), }, }

总结 【Pinia快速入门-上手指南】总得来说,Pinia 就是 Vuex 的官方替代版,可以更好的支持 Vue2,Vue3以及TypeScript。在 Vuex 的基础上去掉了 Mutation模块嵌套等概念,语法更简洁直接, 更符合 Vue3 的 Composition api,为 TypeScript 提供了更好的类型推导。以上是 Pinia.js 用法的一些介绍,Pinia.js 的内容还远不止这些,更多内容及使用有待大家自己探索。Pinia文档
参考文章
  • Vue3新版中文文档
  • Pinia文档
  • 新一代状态管理工具,Pinia.js 上手指南
  • 大菠萝?Pinia已经来了,再不学你就out了
  • pinia快速入门 (一)

    推荐阅读