一、环境搭建
1.1 安装
npm i pinia
1.2 引用
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
const store =createPinia()
export const app = createApp(App)
app.use(store)
app.mount('#app')
二、简单使用
2.1 初始化
创建枚举类 store-name.ts
export const enum Names {
TEST = "TEST"
}
创建 store
类
import {defineStore} from 'pinia'
import {Names} from "./store-name"
export const useTestStore = defineStore(Names.TEST,{
state:()=>{
return {
current:1,
name:'xyy'
}
},
// 类似于computed,有缓存
getters:{
},
// 类似于 methods,可以做同步、异步、提交
actions:{
}
})
2.2 使用
<template>
{{ Test.current }} --- {{ Test.name }}
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
</script>
三、修改 store 值
3.1 直接修改
<template>
{{ Test.current }} --- {{ Test.name }}
<br>
<button @click="change">change</button>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
const change = ()=>{
Test.current++
}
</script>
3.2 $patch 批量修改
<template>
{{ Test.current }} --- {{ Test.name }}
<br>
<button @click="change">change</button>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
const change = ()=>{
Test.$patch({
current:888,
name:"xyy123"
})
}
</script>
3.3 $patch 函数处理
<template>
{{ Test.current }} --- {{ Test.name }}
<br>
<button @click="change">change</button>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
const change = ()=>{
Test.$patch((state)=>{
state.current = 999
state.name = "zhangsan"
})
}
</script>
3.4 $state 批量修改
<template>
{{ Test.current }} --- {{ Test.name }}
<br>
<button @click="change">change</button>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
const change = ()=>{
Test.$state = {
current:111,
name:"xyy567"
}
}
</script>
3.5 action
在 store 中的action 添加修改逻辑
import {defineStore} from 'pinia'
import {Names} from "./store-name"
export const useTestStore = defineStore(Names.TEST,{
state:()=>{
return {
current:1,
name:'xyy'
}
},
// 类似于computed,有缓存
getters:{
},
// 类似于 methods,可以做同步、异步、提交
actions:{
setCurrent(){
this.current = 555
}
}
})
使用定义好的函数方法
<template>
{{ Test.current }} --- {{ Test.name }}
<br>
<button @click="change">change</button>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
const change = ()=>{
Test.setCurrent()
}
</script>
四、 解构 store
4.1 基础使用
<template>
{{ Test.current }} --- {{ Test.name }}
<br>
<button @click="change">change</button>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
const {current,name} = Test
const change = ()=>{
console.log(current,name)
}
</script>
4.2 常见问题
注意:pinia解构不具有响应式
解决策略:使用storeToRefs
<template>
{{ Test.current }} --- {{ Test.name }}
<br>
<button @click="change">change</button>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
import {storeToRefs} from 'pinia'
const Test = useTestStore()
const {current,name} = storeToRefs(Test)
const change = ()=>{
Test.current++
console.log(current,name)
}
</script>
五、actions
5.1 简单使用
在 store 中的 actions 中为 user 赋值
import {defineStore} from 'pinia'
import {Names} from "./store-name"
type User = {
name:string,
age:number
}
let result:User = {
name:'xyy',
age:23
}
export const useTestStore = defineStore(Names.TEST,{
state:()=>{
return {
user:<User>{},
name:''
}
},
// 类似于computed,有缓存
getters:{
},
// 类似于 methods,可以做同步、异步、提交
actions:{
setUser(){
this.user = result
}
}
})
调用初始化方法
<template>
{{ Test }}
<br>
<button @click="change">change</button>
<br>
</template>
<script setup lang='ts'>
import {useTestStore} from "./store"
const Test = useTestStore()
const change = ()=>{
Test.setUser()
}
</script>
效果如下:
5.2 调用异步方法
import {defineStore} from 'pinia'
import {Names} from "./store-name"
type User = {
name:string,
age:number
}
let result:User = {
name:'xyy',
age:23
}
const login = ():Promise<User>=>{
return new Promise((resolve)=>{
setTimeout(()=>{
resolve({
name:'zhangsan',
age:33
})
},2000)
})
}
export const useTestStore = defineStore(Names.TEST,{
state:()=>{
return {
user:<User>{},
name:''
}
},
// 类似于computed,有缓存
getters:{
},
// 类似于 methods,可以做同步、异步、提交
actions:{
async setUser(){
this.user = await login()
}
}
})
六、getter
6.1 简单使用
定义 getter 内容
获取 getter 内容
getters 也可以调用同类方法
七、api调用
7.1 $reset
作用:重置 store 到他的初始值
7.1 $subscribe
作用:监听器,观察的store有变化时,就会走这个函数
7.2 $onAction
监听 action 中方法
此外,还接受一个参数 true,作用为当组件销毁之后,还继续监听这个事件
八、pinia 持久化插件
8.1 现有问题
当页面刷新后,pinia的状态都会丢失
8.2 解决过程
在main.ts中,注册自定义store插件
import { createApp,toRaw } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia,PiniaPluginContext } from 'pinia'
const store =createPinia()
const setStorage = (key:string,value:string)=>{
localStorage.setItem(key,JSON.stringify(value))
}
const getStorage = (key:string)=>{
return localStorage.getItem(key)?JSON.parse(localStorage.getItem(key) as string) : {}
}
type Options = {
key?:string
}
const __piniaKey__:string = 'defaultKey'
const piniaPlugin = (options:Options) =>{
return (context:PiniaPluginContext) =>{
const {store} = context
const data = getStorage(`${options?.key??__piniaKey__}-${store.$id}`)
console.log(data)
store.$subscribe(()=>{
console.log(toRaw(store.$state))
setStorage(`${options?.key??__piniaKey__}-${store.$id}`,toRaw(store.$state))
})
return {
...data
}
}
}
store.use(piniaPlugin({
key:'pinia'
}))
export const app = createApp(App)
app.use(store)
app.mount('#app')