# Pinia

Pinia

什么是Pinia

  • Pinia(发音为 /piːnjʌ/,如英语中的 “peenya” )是最接近 piña(西班牙语中的菠萝)的词;
    • Pinia 开始于大概 2019 年,最初是作为一个实验为 Vue 重新设计状态管理,让它用起来像组合式 API(Composition API)。
    • 从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容 Vue2、Vue3,也并不要求你使用 Composition API;
    • Pinia 本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、Redux一样);

1661672724638

Pinia和Vuex的区别

  • 那么我们不是已经有 Vuex 了吗?为什么还要用 Pinia 呢?
    • Pinia 最初是为了探索 Vuex 的下一次迭代会是什么样子,结合了 Vuex 5 核心团队讨论中的许多想法;
    • 最终,团队意识到 Pinia 已经实现了 Vuex5 中大部分内容,所以最终决定用 Pinia 来替代 Vuex;
    • 与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API;
    • 最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持;
  • 和 Vuex 相比,Pinia 有很多的优势:
    • 比如 mutations 不再存在
      • 他们经常被认为是非常冗长;
      • 他们最初带来了 devtools 集成,但这不再是问题;
    • 更友好的 TypeScript 支持,Vuex 之前对 TS 的支持很不友好;
    • 不再有 modules 的嵌套结构
      • 你可以灵活使用每一个 store,它们是通过扁平化的方式来相互使用的;
    • 也不再有命名空间的概念,不需要记住它们的复杂关系;

Pinia的使用

  • 01 安装 Pinia : npm install pinia
  • 02 创建 Pinia 实例对象: ./scr/store/index.js : , 再注册即可,该文件无需再做其他操作
1
2
3
4
5
import { createPinia } from "pinia";

const pinia = createPinia();

export default pinia;
  • 03 入口文件注册 Pinia ./src/main.js
1
2
3
4
5
6
7
8
9
10
11
import { createApp } from "vue";
import App from "./App.vue";

// 导入创建的 Pinia 的实例对象
import pinia from "./store/index.js";

const app = createApp(App);

// 注册 Pinia
app.use(pinia);
app.mount("#app");
  • 04 使用 Pinia
    • 注意 Store 获取到后不能解构,否则会失去响应式:
      • 为了从 Store 中提取属性同时保持其响应式,您需要使用 storeToRefs() 。

1661674623889

操作State

  • 读取和写入 state:
    • 默认情况下,您可以通过 store 实例访问状态来直接读取和写入状态;
  • 改变 State:
    • 除了直接用 store.counter++ 修改 store,你还可以调用$patch方法;
    • 它允许您使用部分 “state” 对象同时应用多个更改;
  • 重置 State:
    • 你可以通过调用 store 上的$reset()方法将状态重置到其初始值;

1661675801257

Getters

  • Getters 相当于 Store 的计算属性:
    • 它们可以用 defineStore() 中的 getters 属性定义;
    • getters 中可以定义接受一个 state 作为参数的函数;

1661676968632

  • Getters 也可以返回一个函数,这样就可以接受参数:

image-20230312105729761

actions

  • Actions 相当于组件中的 methods。
    • 可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑;

image-20230312105833208

  • 和 getters 一样,在 action 中可以通过 this 访问整个 store 实例的所有操作;
  • 并且 Actions 中是支持异步操作的,并且我们可以编写异步函数,在函数中使用 await;

image-20230312105853388