【pinia源码】系列文章
- 【pinia源码】一、createPinia源码解析
- 【pinia源码】二、defineStore源码解析
- 【pinia源码】三、storeToRefs源码解析
- 【pinia源码】四、mapHelper API源码解析
目录
前言
【pinia源码】系列文章主要分析pinia的实现原理。该系列文章源码参考pinia v2.0.14。
源码地址:https://github.com/vuejs/pinia
本篇文章将分析defineStore的实现。
使用
通过defineStore定义一个store。
const useUserStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
// or
const useUserStore = defineStore({
id: 'counter',
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
// or
const useUserStore = defineStore('counter', () => {
const count = ref(0)
function increment() {
count.value++
}
return {
count, increment }
})
defineStore
export function defineStore(
idOrOptions: any,
setup?: any,
setupOptions?: any
): StoreDefinition {
let id: string
let options:
| DefineStoreOptions<
string,
StateTree,
_GettersTree<StateTree>,
_ActionsTree
>
| DefineSetupStoreOptions<
string,
StateTree,
_GettersTree<StateTree>,
_ActionsTree
>
const isSetupStore = typeof setup === 'function'
if (typeof idOrOptions === 'string') {
id = idOrOptions
options = isSetupStore ? setupOptions : setup
} else {
options = idOrOptions
id = idOrOptions.id
}
function useStore(pinia?: Pinia | null, hot?: StoreGeneric): StoreGeneric {
// ... }
useStore.$id = id
return useStore
}
defineStore函数可以接收三个参数:idOrOptions、setup、setOptions,后两个参数为可选参数。下面是三个defineStore的函数类型定义。
export function defineStore<
Id extends string,
S extends StateTree = {
},
G extends _GettersTree<S> = {
},
A /* extends ActionsTree */ = {
}
>(
id: Id,
options: Omit<DefineStoreOptions<Id, S, G, A>, 'id'>
): StoreDefinition<Id, S, G, A>
export function defineStore<
Id extends string,
S extends StateTree = {
},
G extends _GettersTree<S> = {
},
A /* extends ActionsTree */ = {
}
>(options: DefineStoreOptions<Id, S, G, A>): StoreDefinition<Id, S, G, A>
export function defineStore<Id extends string, SS>(
id: Id,
storeSetup: () => SS,
options?: DefineSetupStoreOptions<
Id,
_ExtractStateFromSetupStore<SS>,
_ExtractGettersFromSetupStore<SS>,
_ExtractActionsFromSetupStore<SS>
>
): StoreDefinition<
Id,
_ExtractStateFromSetupStore<SS>,
_ExtractGettersFromSetupStore<SS>,
_ExtractActionsFromSetupStore<SS>
>
首先在defineStore中声明了三个变量:id、options、isSetupStore,其中id为定义的store的唯一id,options为定义store时的options,isSetupStore代表传入的setup是不是个函数。
然后根据传入的idOrOptions的类型,为id、otions赋值。紧接着声明了一个useStore函数,并将id赋给它,然后将其return。截止到此,我们知道defineStore会返回一个函数,那么这个函数具体是做什么的呢?我们继续看useStore的实现。
useStore
function useStore(pinia?: Pinia | null, hot?: StoreGeneric): StoreGeneric {
// 获取当前实例
const currentInstance = getCurrentInstance()
// 测试环境下,忽略提供的参数,因为总是能使用getActivePinia()获取pinia实例
// 非测试环境下,如果未传入pinia,则会从组件中使用inject获取pinia
pinia =
(__TEST__ && activePinia && activePinia._testing ? null : pinia) ||
(currentInstance && inject(piniaSymbol))
// 设置激活的pinia
if (pinia) setActivePinia(pinia)
// 如果没有activePinia,那么可能没有install pinia,开发环境下进行提示
if (__DEV__ && !activePinia) {
throw new Error(
`[🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?\n` +
`\tconst pinia = createPinia()\n` +
`\tapp.use(pinia)\n` +
`This will fail in production.`
)
}
// 设置pinia为激活的pinia
pinia = activePinia!
// 从pina._s中查找id否注册过,如果没有被注册,创建一个store并注册在pinia._s中
if (!pinia._s.has(id)) {
if (isSetupStore) {
createSetupStore(id, setup, options, pinia)
} else {
createOptionsStore(id, options as any, pinia)
}
if (__DEV__) {
useStore._pinia = pinia
}
}
// 从pinia._s中获取id对应的store
const store: StoreGeneric = pinia._s.get(id)!
if (__DEV__ && hot) {
const hotId = '__hot:' + id
const newStore = isSetupStore
? createSetupStore(hotId

本文详细分析了Pinia库中`defineStore`的实现原理,包括`createSetupStore`和`createOptionsStore`的创建过程。`defineStore`根据传入参数的不同,创建setup风格或options风格的store。在`useStore`中,根据组件实例获取或注入Pinia,并在Pinia的订阅列表中注册store。文章还探讨了`$onAction`、`$patch`、`$reset`、`$subscribe`等关键方法的实现,以及store的创建和销毁过程。
最低0.47元/天 解锁文章
431

被折叠的 条评论
为什么被折叠?



