Initial commit
This commit is contained in:
224
docs/vue/pinia.md
Normal file
224
docs/vue/pinia.md
Normal 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)
|
||||
```
|
||||
Reference in New Issue
Block a user