手写pinia持久化插件

324 阅读1分钟

安装后pinia

yarn add pinia

手写持久化插件

利用localStorage作持久化,也可以使用cookie

配置pinia

import { createPinia type PiniaPluginContext} from 'pinia'

const store = createPinia()
store.use(piniaPlugin({           //pinia官网支持自定义插件
    key:'pinia'
}))

app.use(store)

持久化函数

思路,默认取值更新state,修改state则重新把整个state更新存储

type Options ={      
    key?:string
}
const _piniaKey_:string = 'wsw'  //如果无传键值前缀,则使用这个作为前缀
const setStorage = (key:string,value:any)=>{             //保存
    localStorage.setItem(key,JSON.stringify(value))
}

const getStorage =(key:string)=>{  //取值
    return localStorage.getItem(key)?JSON.parse(localStorage.getItem(key)as string):{}
}

//自定义pinia插件
const piniaPlugin = (options:Options)=>{  context为默认第一个插件参数,由于插件需要传参,这里用函数柯里化处理
   return (context:PiniaPluginContext)=>{
    const {store} = context //多少个实例生成多少个context
    const data = getStorage(`${options.key ??_piniaKey_}-${store.$id}`) //取值作持久化,取完return出去
    store.$subscribe(()=>{       //store的$subscribe函数,每次store值发生改变时触发
        setStorage(`${options.key ??_piniaKey_}-${store.$id}`,toRaw(store.$state) )//注意把proxy对象还原普通对象,而且是把整个state存储
    })
    return data   //pinia插件可以没返回值,返回值为store的state,同名更新值,原state否则不变      
   }
   
    
}
const store = createPinia()
store.use(piniaPlugin({   //作标记避免键名重复
    key:'pinia'
}))


const app = createApp(App)

app.use(store)