pinia 核心源码
记录pinia核心源码阅读笔记,这里跳过hmr(热更新), mapHelpers(class 工具)等工具源码。 剔除的部分vue2.0兼容代码。 当前pinia版本2.0.13
执行流程概述
- 创建pinia实例,挂载到vue
- 定义state
- 创建组件
- 调用useState
- 生成并缓存pinia
- 注销组件
- 注销监听
rootStore.js
这里主要提供 activePinia(当前可用pinia实例)缓存对象。 并提供两个操作方法,
- setActivePinia 更新 activePinia
export const setActivePinia = (pinia: Pinia | undefined) =>
(activePinia = pinia)
- getActivePinia 获取 activePinia
export const getActivePinia = () =>
// 这里优先返回全局注册的pinia实例
(getCurrentInstance() && inject(piniaSymbol)) || activePinia
subscriptions.ts
响应事件相关, 提供两个方法
- addSubscription
// 向当前state事件队列中注册事件回调
export function addSubscription<T extends _Method>( subscriptions: T[],
callback: T,
detached?: boolean,
onCleanup: () => void = noop ) {
subscriptions.push(callback)
const removeSubscription = () => {
const idx = subscriptions.indexOf(callback)
if (idx > -1) {
subscriptions.splice(idx, 1)
onCleanup()
}
}
// 默认组件注销时,清理事件回调
if (!detached && getCurrentInstance()) {
onUnmounted(removeSubscription)
}
return removeSubscription
}
- triggerSubscriptions
// 执行事件队列
export function triggerSubscriptions<T extends _Method>( subscriptions: T[],
...args: Parameters<T> ) {
subscriptions.slice().forEach((callback) => {
callback(...args)
})
}
createPinia.ts
创建pinia实例
export function createPinia(): Pinia {
// 创建响应式空间,空值pinia相关的响应对象的有效性
const scope = effectScope(true)
// state缓存空间, 生成的store将缓存到该队列中
// 当使用useState是,将通过注册的id,从stateTrue
// 中查询对应的store,保证不同组件使用相同的store
const state = scope.run<Ref<Record<string, StateTree>>>(() =>
ref<Record<string, StateTree>>({})
)!
// 插件队列
let _p: Pinia['_p'] = []
let toBeInstalled: PiniaPlugin[] = []
// 创建pinia实例
// markRaw 保证pinia不会被代理
const pinia: Pinia = markRaw({
// 将pinia实例注册到Vue实例中
install(app: App) {
// 激活当前pinia实例,
setActivePinia(pinia)
if (!isVue2) {
// 设置vue实例
pinia._a = app
// 通过依赖注入设置全局默认pinia实例
// 后面useState会用到
app.provide(piniaSymbo