Initial commit

This commit is contained in:
wfz
2026-05-13 16:24:00 +08:00
commit 5728d3cbda
55 changed files with 37267 additions and 0 deletions

224
docs/vue/pinia.md Normal file
View File

@@ -0,0 +1,224 @@
# 状态管理
## Pinia基础
### 安装Pinia
```bash
npm install pinia
```
### 创建Store
```javascript
// stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
// state
const count = ref(0)
// getters
const doubleCount = computed(() => count.value * 2)
// actions
function increment() {
count.value++
}
function decrement() {
count.value--
}
async function fetchCount() {
// 异步操作
const response = await fetch('/api/count')
const data = await response.json()
count.value = data.count
}
return { count, doubleCount, increment, decrement, fetchCount }
})
```
### 使用Store
```vue
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
// 读取state
console.log(counter.count)
// 读取getters
console.log(counter.doubleCount)
// 调用actions
counter.increment()
</script>
<template>
<div>
<p>Count: {{ counter.count }}</p>
<p>Double: {{ counter.doubleCount }}</p>
<button @click="counter.increment">+1</button>
</div>
</template>
```
## 解构Store
### storeToRefs
```vue
<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
// 解构state和getters保持响应性
const { count, doubleCount } = storeToRefs(counter)
// 解构actions直接解构
const { increment, decrement } = counter
</script>
```
## 持久化
### 安装插件
```bash
npm install pinia-plugin-persistedstate
```
### 配置持久化
```javascript
// stores/index.js
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
export default pinia
```
### 使用持久化
```javascript
// stores/user.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useUserStore = defineStore('user', () => {
const token = ref('')
const userInfo = ref(null)
function setToken(newToken) {
token.value = newToken
}
function setUserInfo(info) {
userInfo.value = info
}
function logout() {
token.value = ''
userInfo.value = null
}
return { token, userInfo, setToken, setUserInfo, logout }
}, {
persist: {
key: 'my-user-store',
storage: localStorage,
paths: ['token', 'userInfo']
}
})
```
## 组合多个Store
```javascript
// stores/index.js
import { useCounterStore } from './counter'
import { useUserStore } from './user'
export function useRootStore() {
const counter = useCounterStore()
const user = useUserStore()
function resetAll() {
counter.$reset()
user.$reset()
}
return {
counter,
user,
resetAll
}
}
```
## 订阅状态变化
```vue
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
// 订阅state变化
counter.$subscribe((mutation, state) => {
console.log('类型:', mutation.type)
console.log('storeId:', mutation.storeId)
console.log('新状态:', state)
// 持久化到本地存储
localStorage.setItem('counter', JSON.stringify(state))
})
// 订阅actions
counter.$onAction(({ name, args, after, onError }) => {
console.log(`Action ${name} 被调用,参数:`, args)
after((result) => {
console.log(`Action ${name} 完成,结果:`, result)
})
onError((error) => {
console.error(`Action ${name} 出错:`, error)
})
})
</script>
```
## 插件开发
```javascript
// plugins/piniaLogger.js
export function piniaLogger({ store }) {
store.$onAction(({ name, args, after, onError }) => {
console.log(`[${store.$id}] ${name} 开始`, args)
after((result) => {
console.log(`[${store.$id}] ${name} 完成`, result)
})
onError((error) => {
console.error(`[${store.$id}] ${name} 失败`, error)
})
})
}
// 使用插件
const pinia = createPinia()
pinia.use(piniaLogger)
```