前面章节介绍了Pinia的使用,本章节用两个场景介绍下Pinia的插件开发
- reset方法
- 自动储存storage功能,
注册插件
先回顾下pinia是如何在vue中注册的
import { createApp } from 'vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
pinia的插件实际上就是一个函数,只需要调用createPinia().use()方法即可注册插件
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import {piniaPlugins} from "@/plugins/piniaPlugins";
const app = createApp(App)
// 创建pinia
const pinia = createPinia()
// 注册pinia插件
pinia.use(piniaPlugins)
// 将pinia在vue中注册
app.use(pinia)
app.mount('#app')
pinia插件是一个函数,函数接受一个PiniaPluginContext类型的参数
import {PiniaPluginContext} from "pinia";
export function piniaPlugins({pinia, app, store, options}: PiniaPluginContext){
// pinia: pinia实例
// app: vue实例
// store: 当前调用defineStore的状态
// options: 当前调用defineStore的配置
}
封装reset方法
pinia的使用风格与vue一样,分为Options API和Composition API。但在使用Composition API时发现,$reset方法不能正常使用,于是打算自己封装一个
export function piniaPlugins({store}: PiniaPluginContext){
// 深拷贝初始状态
const state = deepClone(store.$state)
// 向当前状态store里添加reset方法
store.reset = function (){
// reset方法将状态替换为初始状态
store.$state = state
}
}
使用
export const useCountStore = defineStore('countTest', ()=>{
const count = ref(0)
return {
count
}
})
const countStore = useCountStore()
function onReset(){
countStore.reset()
}
自动储存storage功能
我们使用全局状态时经常需要数据持久化,通常做法就是在actions方法里将新的值保存在storage里
export const useTokenStore = defineStore('tokenTest', {
state: ()=>({
token: localStorage.getItem('token')
}),
actions: {
changeToken(tokenNew: string){
this.token = tokenNew
localStorage.setItem('token', tokenNew)
}
}
})
下面来封装下这个方法,让插件帮你实现这个功能
export function piniaPlugins({store, options}: PiniaPluginContext){
// 约定个options.saveLocal字段,来判断这个模块需不需要自动储存storage功能
if(options.saveLocal){
// 初始化时讲所有状态的默认值保存在Storage里
for (const stateKey in store.$state) {
if(localStorage.getItem(stateKey)){
// 如果存在该字段则取出来并设置到状态里
store.$state[stateKey] = localStorage.getItem(stateKey)
}else{
localStorage.setItem(stateKey, store.$state[stateKey])
}
}
// 订阅状态的修改,更新
store.$subscribe((mutation, state)=>{
if(mutation.type === 'direct'){
let stateKey = mutation.events.key
localStorage.setItem(stateKey, state[stateKey])
}else{
mutation.events.forEach(event=>{
let stateKey = event.key
localStorage.setItem(stateKey, state[stateKey])
})
}
})
}
}
定义状态
export const useCountStore = defineStore('countTest', ()=>{
const count = ref(0)
return {
count
}
},{
// 启用 saveLocal
saveLocal: true
})
使用
const countStore = useCountStore()
function onClick(){
// 这样不管哪种修改方式都能正确的设置到Storage里
countStore.count++
countStore.$state = {
count: 100
}
countStore.$state.count++
countStore.$patch({
count: countStore.count+1
})
countStore.$patch((state)=>{
state.count++
})
countStore.changeCount(100)
}