Skip to content

一. Pinia 和 Vuex 的对比


1. 什么是 Pinia 呢?

  • Pinia(发音为 /piːnjʌ/,如英语中的“peenya”)是最接近 piña(西班牙语中的菠萝)的词

    • Pinia 开始于大概2019年,最初是作为一个实验为 Vue 重新设计状态管理,让它用起来像组合式 APIComposition API

    • 从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容 Vue2Vue3,也并不要求你使用 Composition API

    • Pinia 本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和 VuexRedux 一样)

      image-20220806211539366

2. Pinia 和 Vuex 的区别

  • 那么我们不是已经有 Vuex 了吗?为什么还要用 Pinia 呢?

    • Pinia 最初是为了探索 Vuex 的下一次迭代会是什么样子,结合了 Vuex5 核心团队讨论中的许多想法
    • 最终,团队意识到 Pinia 已经实现了 Vuex5 中大部分内容,所以最终决定用 Pinia 来替代 Vuex
    • Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API
    • 最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持
  • Vuex 相比,Pinia 有很多的优势:

    • mutations 不再存在

      • 它们经常被认为是非常冗长
      • 它们最初带来了 devtools 集成,但这不再是问题
    • 更友好的 TypeScript 支持Vuex 之前对 TS 的支持很不友好

    • 不再有 modules 的嵌套结构

      • 你可以灵活使用每一个 store,它们是通过扁平化的方式来相互使用的
    • 不再有命名空间的概念,不需要记住它们的复杂关系

      image-20220806211833662

二. 创建 Pinia 的 Store


1. 如何使用 Pinia?

  • 使用 Pinia 之前,我们需要先对其进行安装:

    bash
    # npm
    npm i pinia
    
    # yarn
    yarn add pinia
  • 创建一个 pinia 并且将其传递给应用程序:

    image-20220806223500226

2. 认识 Store

  • 什么是 Store
    • 一个 Store(如 Pinia)是一个实体,它会持有为绑定到你组件树的状态和业务逻辑,也就是保存了全局的状态
    • 它有点像始终存在,并且每个人都可以读取和写入的组件
    • 你可以在你的应用程序中定义任意数量的 Store 来管理你的状态
  • Store 有三个核心概念:
    • stategettersactions
    • 等同于组件的 datacomputedmethods
    • 一旦 store 被实例化,你就可以直接在 store 上访问 stategettersactions 中定义的任何属性

3. 定义一个 Store

  • 定义一个 Store

    • 我们需要知道 Store 是使用 defineStore() 定义的
    • 并且它需要一个唯一名称,作为第一个参数传递
  • 这个 name,也称为 id,是必要的,Pinia 使用它来将 store 连接到 devtools

  • 返回的函数统一使用 useXxx 作为命名方案,这是约定的规范

    image-20220806223847056

4. 使用定义的 Store

  • Store 在它被使用之前是不会创建的,可以通过调用 use 函数来使用 Store

  • 注意 Store 获取到后不能被解构,那么会失去响应式:

    • 为了从 Store 中提取属性同时保持其响应式,您需要使用 storeToRefs()

      image-20220806224135989

总结:

  • store 只有在被使用时,才会被创建
  • store 获取到后不能被解构,否则会失去响应式
  • 如果想要保持解构的属性的响应式,使用 storeToRefs()

三. Pinia 核心概念 State


1. 认识和定义 State

  • statestore 的核心部分,因为 store 是用来帮助我们管理状态的

    • Pinia 中,状态被定义为返回初始状态的函数

      js
      export const useCounter = defineStore('counter', {
        state: () => ({
          counter: 0,
          name: 'later',
          age: 18
        })
      })

2. 操作 State

  • 读取和写入 state

    • 默认情况下,可以通过 store 实例访问状态来直接读取和写入状态
  • 重置 State

    • 可以通过调用 store 上的 $reset() 方法将状态重置到其初始值
  • 更改 State

    • 除了直接用 store.counter++ 修改 store,还可以调用 $patch 方法
    • 它允许您使用部分 state 对象同时应用多个更改
  • 替换 State

    • 可以通过将其 $state 属性设置为新对象来替换 Store 的整个状态
    • 从代码角度来说,应该是指向另外一个对象,但从测试结果来看,应该是对 xxx.$state 进行 set 操作的时候拦截了,并没有指向一个新的对象,而是替换原对象中同名的属性
    image-20220807134404112

四. Pinia 核心概念 Getters


1. 认识和定义 Getters

  • Getters 相当于 Store 的计算属性

    • 它们可以用 defineStore() 中的 getters 属性定义

    • getters 中可以定义接受一个 state 作为参数的函数

      image-20220807135951472

2. 访问 Getters

  • 访问当前 storeGetters

    image-20220807140225365
  • Getters 中访问自己的其他 Getters

    • 可以通过 this 来访问到当前 store 实例的所有其他属性

      image-20220807140320214
  • 访问其他 storeGetters

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

    image-20220807140528093

五. Pinia 核心概念 Actions


1. 认识和定义 Actions

  • Actions 相当于组件中的 methods

    • 可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑
  • getters 一样,在 action 中可以通过 this 访问整个 store 实例的所有操作

    image-20220807142632564

2. Actions 执行异步操作

  • 并且 Actions 中是支持异步操作的,并且我们可以编写异步函数,在函数中使用 await

    image-20220807142842638

Released under the MIT License.