Vuex 是 Vue.js 社区中广为人知且成熟的状态管理库
Pinia是Vue.js社区中一个活跃成员写的并且得到了 Vue.js 核心团队的认可和支持,被视为 Vue 3 的首选状态管理解决方案之一。
为什么要使用Vuex或者Pinia
在构建大型或复杂的单页应用时,如果仅依靠父子组件传值来管理数据,会导致数据管理变得非常混乱。因此,我们需要一个专门的工具来管理这些数据,这就是状态管理库的作用。
为什么有Vuex还要开发Pinia? 可以来看看Pinia官方文档 Pinia
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无疑是一个值得推荐的选择。但不管怎样这两种库都有优缺点都值得我们学习,我也正在入门这知识慢慢进步。