Pinia 是 Vue 的轻量级状态管理库,专为 Vue 3 设计(也支持 Vue 2),提供了更简洁的 API 和 TypeScript 支持。以下是 Pinia 的使用方法及示例:
一、安装 Pinia
npm install pinia
# 或
yarn add pinia
二、创建 Pinia 实例
在 main.js
中初始化 Pinia:
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')
三、定义 Store
Pinia 支持组合式 API 和 选项式 API,以下是两种写法:
1. 组合式 API(推荐)
// stores/user.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useUserStore = defineStore('user', () => {
// State
const name = ref('Alice')
const age = ref(25)
// Actions
function updateUser(newName, newAge) {
name.value = newName
age.value = newAge
}
// Getters
const isAdult = computed(() => age.value >= 18)
return { name, age, updateUser, isAdult }
})
2. 选项式 API
// stores/user.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: 'Alice',
age: 25,
}),
actions: {
updateUser(newName, newAge) {
this.name = newName
this.age = newAge
},
},
getters: {
isAdult: (state) => state.age >= 18,
},
})
四、在组件中使用 Store
<!-- UserProfile.vue -->
<script setup>
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
// 修改状态(直接修改或通过 action)
const changeName = () => {
// 直接修改
userStore.name = 'Bob'
// 或通过 action
userStore.updateUser('Bob', 30)
}
// 使用 $patch 批量修改状态
const batchUpdate = () => {
userStore.$patch({
name: 'Charlie',
age: 28,
})
}
</script>
<template>
<div>
<p>Name: {{ userStore.name }}</p>
<p>Age: {{ userStore.age }}</p>
<p>Is Adult: {{ userStore.isAdult ? 'Yes' : 'No' }}</p>
<button @click="changeName">Update User</button>
<button @click="batchUpdate">Batch Update</button>
</div>
</template>
五、核心概念
-
State
存储应用状态,通过store.xxx
直接访问或修改。 -
Actions
定义方法修改状态,支持同步和异步操作。 -
Getters
计算属性,通过computed
派生状态。 -
**reset()∗∗重置状态到初始值:‘userStore.reset()** 重置状态到初始值:`userStore.reset()∗∗重置状态到初始值:‘userStore.reset()`
-
$subscribe
监听状态变化:userStore.$subscribe((mutation, state) => { console.log('State changed:', state) })
六、完整示例:计数器
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++
},
async incrementAsync() {
setTimeout(() => this.count++, 1000)
},
},
getters: {
doubleCount: (state) => state.count * 2,
},
})
<!-- Counter.vue -->
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<div>
<p>Count: {{ counter.count }}</p>
<p>Double: {{ counter.doubleCount }}</p>
<button @click="counter.increment()">Increment</button>
<button @click="counter.incrementAsync()">Async Increment</button>
</div>
</template>
七、总结
Pinia 的使用步骤:
- 安装并注册 Pinia。
- 使用
defineStore
定义 Store(组合式或选项式)。 - 在组件中通过
useXxxStore()
获取 Store 实例。 - 直接访问状态、调用 Actions 或使用 Getters。
Pinia 的简洁性和 TypeScript 支持使其成为 Vue 状态管理的理想选择。