Vue.js 状态管理库 Pinia
概述
Pinia 是一个用于 Vue.js 应用程序的状态管理库。它是由 Vue Storefront 团队开发的,旨在提供简单、可扩展且高效的状态管理解决方案。
Pinia 基于 Vue 3 的新响应式系统,并通过使用 TypeScript 提供了强类型支持。它提供了一个类似于 Vuex 的 API,但在某些方面更加简洁和直观。
使用 Pinia,你可以定义和管理应用程序的状态,将其存储在一个或多个 store 中。每个 store 代表
了一部分应用程序的状态和相关的操作方法。
特点
-
基于 Vue 3:Pinia 利用了 Vue 3 的响应式系统,并与其无缝集成。它能够充分利用 Vue 3 的性能优势和改进的开发体验。
-
TypeScript 支持:Pinia 提供了对 TypeScript 的内置支持,可以提供类型检查和智能提示,使开发者能够更轻松地编写类型安全的代码。
-
简洁的 API:Pinia 的 API 设计简单且直观,类似于 Vuex,但更加精简。它提供了一组易于理解和使用的方法,使状态管理变得简单而高效。
-
插件生态系统:Pinia 支持插件系统,可以通过插件扩展和增强其功能。这使得开发者可以根据项目的需要添加自定义逻辑和功能。
-
开箱即用的特性:Pinia 提供了一些常用的特性,如模块化组织、状态持久化、插件支持等。这些功能可以帮助开发者更好地组织和管理应用程序的状态。
开始
安装
npm install pinia
在 Vue 3 中使用
// Vue 3
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
// stores/main.ts
import { defineStore } from 'pinia'
// main 是 store 的名称,在整个应用程序中必须是唯一的,将显示在开发者工具中
export const useMainStore = defineStore('main', {
// 一个返回新状态的函数
state: () => ({
counter: 0,
name: 'Eduardo',
}),
// 可选的 getter
getters: {
// getters 的第一个参数是状态对象
doubleCounter: (state) => state.counter * 2,
// 在其他 getter 中使用 getter
doubleCounterPlusOne(): number {
return this.doubleCounter + 1
},
},
// 可选的 action
actions: {
reset() {
// `this` 是 store 实例
this.counter = 0
},
},
})
在 Nuxt 3 中使用
npm install @pinia/nuxt -D
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
[
"@pinia/nuxt",
{
autoImports: [
// 自动引入 `defineStore()`
"defineStore",
// 自动引入 `defineStore()` 并重命名为 `definePiniaStore()`
["defineStore", "definePiniaStore"],
],
},
],
]
});
// stores/counter.ts
export const useCounterStore = defineStore("counter", {
state: () => ({ count: 2 }),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++;
},
},
});
组件调用
App.vue
<template>
<p>{{ store.count }}</p>
<button @click="store.increment">加一</button>
</template>
<script setup lang="ts">
import { useCounterStore } from "@/stores/counter";
const store = useCounterStore();
</script>
如果你需要用解构赋值语法来命名变量,请先使用 storeToRefs
将其变回为响应式。
❌
// 不要这样写,因为这样会破坏响应式
// 这与从 `props` 进行解构赋值是相同的
const { name, doubleCount } = store;
✔️
import { storeToRefs } from "pinia";
const { name, doubleCount } = storeToRefs(store);