Pinia
是 Vue 3 官方推荐的状态管理库,用于代替 Vue 2 中的 Vuex
。Pinia
的核心设计目标是提供简单、灵活、轻量的状态管理方式,并与 Vue 3 的组合式 API 紧密结合。它使得状态管理更加直观,同时保留了响应式和开发者工具的调试支持。
为什么选择 Pinia?
轻量灵活:相比 Vuex
,Pinia
更加轻量化,代码更简洁,并且 API 更加直观易用。
组合式 API 支持:Pinia
与 Vue 3 的组合式 API 紧密集成,可以很方便地与 ref
、computed
和 watch
结合。
模块化设计:Pinia
不再使用 Vuex 的模块系统,而是通过 store
的定义方式让代码组织更自由,可以创建多个独立的 store
。
TypeScript 支持:Pinia
对 TypeScript 友好,开发时能够获得自动补全、类型检查等优势。
安装 pinia
首先,我们需要在 Vue 3 项目中安装 pinia
。
npm install pinia
安装完成后,接下来需要在项目入口文件中进行初始化。
在 Vue 项目中使用 Pinia
1. 注册 Pinia
在 main.js
文件中引入并注册 pinia
。
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.mount('#app');
2. 创建一个 Store
Pinia 的 store
可以看作是一个独立的模块,用来存储和管理全局的状态。在 src/stores
文件夹下创建一个新的 store
,如 useUserStore.js
。
// src/stores/useUserStore.js
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
// 存储状态的地方,相当于 Vuex 的 state
state: () => ({
name: 'John',
age: 25
}),
// 相当于 Vuex 的 getters,用于计算状态
getters: {
doubleAge(state) {
return state.age * 2;
}
},
// 相当于 Vuex 的 mutations 和 actions,用于同步或异步地修改状态
actions: {
updateName(newName) {
this.name = newName;
},
incrementAge() {
this.age += 1;
}
}
});
state
:定义需要存储的状态。
getters
:类似于 Vuex 中的计算属性,用于从状态派生数据。
actions
:用于修改状态,可以包含异步逻辑。
3. 在组件中使用 Store
我们可以在组件中使用 useUserStore
,并通过 state
、getters
和 actions
来访问和修改状态。
<template>
<div>
<h1>{{ name }}</h1>
<p>年龄:{{ age }}</p>
<p>年龄的两倍:{{ doubleAge }}</p>
<input v-model="newName" placeholder="输入新名字" />
<button @click="changeName">修改名字</button>
<button @click="incrementAge">增加年龄</button>
</div>
</template>
<script>
import { ref } from 'vue';
import { useUserStore } from '@/stores/useUserStore';
export default {
setup() {
const userStore = useUserStore(); // 调用 useUserStore 获取 store 实例
const newName = ref('');
const changeName = () => {
userStore.updateName(newName.value); // 调用 actions 修改名字
};
return {
name: userStore.name,
age: userStore.age,
doubleAge: userStore.doubleAge, // 调用 getter
newName,
changeName,
incrementAge: userStore.incrementAge // 调用 actions 增加年龄
};
}
};
</script>
在这里,我们通过 useUserStore
引入了 store
,并将状态、getters 和 actions 绑定到组件的 setup
函数中。我们可以使用 store
中的 state
、getters
以及 actions
来响应用户的操作。
4. 使用 TypeScript
Pinia
对 TypeScript 支持非常友好。下面我们展示如何在 Pinia
中使用 TypeScript。
首先,定义 state
、getters
和 actions
的类型:
// src/stores/useUserStore.ts
import { defineStore } from 'pinia';
interface UserState {
name: string;
age: number;
}
export const useUserStore = defineStore('user', {
state: (): UserState => ({
name: 'John',
age: 25
}),
getters: {
doubleAge: (state) => state.age * 2
},
actions: {
updateName(newName: string) {
this.name = newName;
},
incrementAge() {
this.age += 1;
}
}
});
5. 持久化状态
Pinia
可以与插件结合,将状态持久化到 localStorage
或 sessionStorage
。可以使用 pinia-plugin-persistedstate
插件来实现这一功能。
安装插件:
npm install pinia-plugin-persistedstate
然后在 pinia
初始化时注册插件:
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
在 store 中启用持久化:
export const useUserStore = defineStore('user', {
state: () => ({
name: 'John',
age: 25
}),
persist: true // 开启持久化
});
这样,每次刷新页面时,状态都会从 localStorage
或 sessionStorage
中恢复。
总结
Pinia
是 Vue 3 中的全新状态管理工具,它的轻量、灵活、与组合式 API 的紧密集成使得它成为 Vuex
的理想替代品。在实际项目中使用 Pinia
可以大大简化代码逻辑,使得状态管理更加直观且易于维护。