你知道的状态管理库Pinia

476 阅读5分钟

Vuex 是 Vue.js 社区中广为人知且成熟的状态管理库

Pinia是Vue.js社区中一个活跃成员写的并且得到了 Vue.js 核心团队的认可和支持,被视为 Vue 3 的首选状态管理解决方案之一。

为什么要使用Vuex或者Pinia

在构建大型或复杂的单页应用时,如果仅依靠父子组件传值来管理数据,会导致数据管理变得非常混乱。因此,我们需要一个专门的工具来管理这些数据,这就是状态管理库的作用。

为什么有Vuex还要开发Pinia? 可以来看看Pinia官方文档 Pinia

image.png

Pinia可以被视为对Vuex未来迭代设想的实现,特别是它融合了许多Vuex 5讨论中的理念和改进点。Pinia基于Vuex的经验教训和社区反馈而设计,是新一代的状态管理库,而非仅仅是Vuex的简化版本。

Pinia vs. Vuex

Vuex:

  • State: 集中式状态存储,确保全局数据的一致性。
  • Getters: 提供派生状态,基于基本状态计算得出。
  • Mutations: 同步函数,确保状态变更的可预测性和可追踪性。
  • Actions: 异步操作的执行者,用于处理复杂的业务逻辑。

Pinia:

  • State: 响应式状态,允许模块化和局部化管理,提升状态管理的灵活性。
  • Getters: 计算属性,与状态紧密结合,提供衍生状态。
  • Actions: 支持同步和异步操作,简化状态更新逻辑,提升开发效率。

版本与兼容性:

  • Vuex: 当前最新版是 4.x,专门设计用于 Vue 3,同时保持对 Vue 2 的支持(通过 3.x 版本)。
  • Pinia: 当前最新版是 2.x,它不仅同时支持 Vue 2 和 Vue 3,而且在 TypeScript 项目中表现出色,提供更佳的类型推断和代码智能提示。

对比之下,Pinia 显著改善了状态管理的体验,特别是在 TypeScript 项目中,其简洁的 API 和直观的使用方式解决了 Vuex 中的许多痛点。Pinia 的设计更加符合现代开发实践,尤其是与 Vue 3 Composition API 结合使用时,展现出更强的模块化能力和更好的性能表现。因此,对于正在构建或重构项目,尤其是那些采用 TypeScript 的项目,强烈建议考虑使用 Pinia,它不仅能够简化状态管理,还能提升开发速度和代码质量。

Pinia使用

首先就是安装Pinia

npm install pinia

来到main.js初始化配置

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
app
    .use(createPinia())
    .mount('#app')

再创建一个store文件夹在里面创建一个pinia.js,定义Store

import { defineStore } from 'pinia'

export const useAlertsStore = defineStore('alerts', {
  // 其他配置...
})

这里defineStore接受两个参数,第一个参数是 Store 的唯一名称,它应该在整个应用范围内是唯一的。这个名称会被 Pinia 用来识别和管理 Store 的实例。第二个参数是一个对象,包含了 Store 的配置选项。

State

这个就是我们store的核心

import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  // 为了完整类型推理,推荐使用箭头函数
  state: () => {
    return {
      // 所有这些属性都将自动推断出它们的类型
      count: 0,
      name: 'Eduardo',
      isAdmin: true,
      items: [],
      hasChanged: true,
    }
  },
})

默认情况下,你可以通过 store 实例访问 state,直接对其进行读写。

import {useStore} from './store/count'
const counterStore = useStore()
counterStore.count++

使用选项式 API 时,你可以通过调用 store 的 $reset() 方法将 state 重置为初始值。

const store = useStore()

store.$reset()

Getter

Getter 是 Store 中用于生成派生状态的方法,它们基于 Store 的状态生成新的值。Getter 是响应式的,也就是说,如果它们依赖的 state 发生变化,那么它们的值也会自动更新。

import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => ({
    count: 0,
    name: 'Eduardo',
    isAdmin: true,
    items: [],
    hasChanged: true,
  }),
  getters: {
    // Getter 的命名通常以 `get` 开头,但这不是强制性的
    getFullname: (state) => {
      // 这里我们使用 state 的属性来生成一个新的值
      return `${state.name} ${state.isAdmin ? 'Admin' : ''}`;
    },
    itemCount: (state) => {
      // 计算 items 数组的长度
      return state.items.length;
    },
  },
})

在你的组件中,你可以像访问普通属性一样访问 Getter:

import { useStore } from './store/count'
const counterStore = useStore()
console.log(counterStore.getFullname); // 输出 "Eduardo Admin"

Action

Action 是 Store 中用于执行业务逻辑的方法。它们可以是同步的,也可以是异步的。Action 不仅可以修改 Store 的状态,还可以包含复杂的异步操作,如 API 调用。

import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => ({
    count: 0,
    name: 'Eduardo',
    isAdmin: true,
    items: [],
    hasChanged: true,
  }),
  getters: {
    // Getter 定义
  },
  actions: {
    // Action 的命名通常表示它将执行的操作
    incrementCount() {
      // 修改 state 的 count 属性
      this.count++;
    },
    async fetchItems() {
      try {
        // 假设我们有一个 API 方法来获取数据
        const response = await fetch('https://api.example.com/items');
        const data = await response.json();
        // 更新 items 属性
        this.items = data;
      } catch (error) {
        console.error('Error fetching items:', error);
      }
    },
  },
})

在组件中调用 Action:

import { useStore } from './store/count'
const counterStore = useStore()
counterStore.incrementCount(); // 增加 count 的值
counterStore.fetchItems(); // 异步获取 items

总结

Pinia和Vuex都是强大的状态管理库,各自有其优点和适用场景。Vuex经过多年的发展和广泛使用,已经成为Vue.js社区中最成熟的状态管理解决方案,尤其是在Vue 2项目中。它提供了清晰的状态管理模式,通过State、Getters、Mutations和Actions分离业务逻辑,使得代码结构清晰且易于维护。

然而,随着Vue 3的引入和现代开发需求的变化,Pinia应运而生。它不仅保留了Vuex的优点,还对其进行了许多改进,使得状态管理更加灵活和高效。Pinia与Vue 3的Composition API无缝集成,提升了代码的可读性和可维护性。此外,Pinia在TypeScript支持方面也表现优异,提供了更好的类型推断和代码智能提示。

在选择状态管理库时,考虑项目的具体需求和开发团队的熟悉程度非常重要。如果你的项目仍在使用Vue 2或者已经习惯了Vuex的使用模式,继续使用Vuex是一个稳妥的选择。而如果你正在启动一个新的Vue 3项目,或者希望利用Vue 3的优势,那么Pinia无疑是一个值得推荐的选择。但不管怎样这两种库都有优缺点都值得我们学习,我也正在入门这知识慢慢进步。