本文最后更新于 46 天前,其中的信息可能已经有所发展或是发生改变。
🎯 为什么选择Pinia?
+ 完全支持TypeScript
+ 零模板代码的简洁API
+ 自动代码分割与热更新
+ Vue DevTools深度集成
- 相比Vuex减少40%的样板代码
🛠️ 5分钟环境配置
1. 创建Vue项目(已创建可跳过)
npm create vue@latest
✔ Add Pinia? Yes
2. 独立安装
npm install pinia
# 或
yarn add pinia
3. 初始化配置
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
💡 核心概念速览
1. Store结构解析
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
// 数据仓库
state: () => ({ count: 0 }),
// 计算属性
getters: {
double: (state) => state.count * 2
},
// 操作方法
actions: {
increment() {
this.count++
}
}
})
2. Composition API用法
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<button @click="counter.increment">
{{ counter.count }} → {{ counter.double }}
</button>
</template>
🔥 六大实用场景
场景1:类型安全的Store
interface UserState {
name: string
age: number
skills: string[]
}
export const useUserStore = defineStore('user', {
state: (): UserState => ({
name: 'John',
age: 25,
skills: ['Vue', 'TypeScript']
})
})
场景2:异步操作处理
actions: {
async fetchUserData() {
try {
const res = await fetch('/api/user')
this.userData = await res.json()
} catch (error) {
console.error('Fetch failed:', error)
}
}
}
场景3:持久化存储
npm install pinia-plugin-persistedstate
javascriptCopy Code// main.js
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
🛠️ 开发调试技巧
1. 状态快照
// 获取当前状态
const snapshot = JSON.stringify(store.$state)
// 恢复状态
store.$state = JSON.parse(snapshot)
🚀 性能优化策略
优化方向 | 实现方案 | 效果提升 |
---|---|---|
自动代码分割 | 按需导入Store | 包体积减少30% |
批量状态更新 | $patch 方法 |
渲染次数减少80% |
计算属性缓存 | Getters自动缓存 | 计算耗时减少60% |
服务端渲染 | 使用useSSRContext |
首屏提速40% |
⚠️ 常见问题指南
1. 响应式丢失问题
// ❌ 错误写法
const { count } = store
// ✅ 正确写法
const count = store.count // 保持响应式
const { count } = storeToRefs(store)
2. Store生命周期
// 重置状态
store.$reset()
// 监听变化
store.$subscribe((mutation, state) => {
console.log('State changed:', mutation.type)
})
3. 跨Store通信
// userStore.js
export const useUserStore = defineStore('user', {
actions: {
async login() {
const cart = useCartStore()
await this.fetchUser()
cart.loadCart()
}
}
})
+ 官方文档推荐:https://pinia.vuejs.org
+ 最佳实践:为每个功能模块创建独立Store
- 避免:在Store中直接操作DOM