手写pinia与思想
pinia
pinia是伴随着vue3的状态管理库,具有可扩展性与类型安全的特点。也就是支持插件和typescript。
手写pinia
const piniaSymbol = Symbol('pinia')
// symbol全局唯一key,避免重复
function createPinia() {
// pinia 全局的pinia
let pinia = {
// app.use(pinia) 这个方法在执行之后会调用pinia的install方法完成安装
// 至于app参数就是将vue的createApp创建出来的实例的this
install(app) {
app.poride(piniaSymbol, pinia)
state: ref({})
// store内的state
_s: new Map()
// 存储每个store
}
}
return pinia
}
// 定义store,组件中通过对象的点语法调用state/getter等
function defineStore(id, options) {
function useStore() {
// 高阶函数 函数执行完成后返回store实例
let pinia = inject(piniaSymbol)
// 提取pinia实例
if (!pinia._s.get(id)) {
// 是否存在重复id的store,重复则直接获取已有的store,否则创建store
createOtionStore(id, options, pinia)
}
let store = pinia._s.get(id)
return store
}
return useStore
}
function createOtionStore(id, options, pinia) {
// const { state, ggetters, actions } = options
let store = reactive({
_p: pinia,
id
})
Object.assign(store, setup())
pinia._s.set(id, store)
function setup() {
const { state, getters, actions } = options
// 判断 pinia.state.value 中是否有值,如果没值则将 state 的调用结果赋值进去
!pinia.state.value[id] && (pinia.state.value[id] = state())
// 此时通过 toRefs 将 pinia.state.value[id] 处理为响应式
let localState = toRefs(pinia.state.value[id])
// 处理getters 时先拿到内部所有的 key 组成的数组
let localGetters = Object.keys(getters).reduce((item, name) => {
// 通过computed,调用时,将this指向store即可完成读取state
item[name] = computed(() => {
const store = pinia._s.get(id)
return getters[name].call(store, store)
})
return item
}, {})
// 此处将 处理后的 state/getters/actions 返回
return Object.assign(localState, localGetters, actions)
}
}
主要由四个大块组成:
- piniaSymbol:symbol的全局变量,唯一的key,避免重复。
- createPinia:用于创建pinia,外部应用使用pinia时,调用pinia内部的install方法即可。它内部使用依赖注入,为外部应用提供pinia对象。且pinia有响应式的state和map结构的stroe集合。
- defineStore:是一个高阶函数,函数执行返回store实例。在这里会提取到pinia的实例,将pinia上的map的store集合设置值。
- createOtionStore:完成上方的pinia上的map的设置store的操作。首先store实例是响应式的,有唯一id,然后将传入的options处理后添加到store实例上。options操作state通过pinia,然后compute作为store上的各类方法。
pinia本身还支持插件,例如持久化的插件,然后就是pinia现在不仅支持options式的api,还可以setup式的,但也就是createOptionsStore换成createSetupStore罢了。他们的内部处理不同系统。
思想
前端的中间件:中间件在后端是耳熟能详的,一般来说也就是扩展项目的插件。在前端其实也差不多,特点就是:调用函数方法创建实例,然后设置实例的一些状态或者拦截器(vueRouter的拦截器),最后外部应用调用实例的install方法就可以了。
前端来说中间件或者应该叫中间件模式,应用的是中间件的思想。
前端插件的中间件比如express,koa,pinia。其实axios也是中间件的思想,特别是封装过的。
然后就是中间件通过symbol来完成依赖注入,全局的设置插件。
其次中间件通过高阶函数的形式返回实例。
以上就是pinia引出的一些思想,学习它主要是pinia具有足够的代表性,且前端来说插件基本上都是使用了中间件这样的思想来完成。
结语
本次的文章到这里就结束啦!♥♥♥读者大大们认为写的不错的话点个赞再走哦 ♥♥♥
每天一个知识点,每天都在进步!♥♥