前言
????之前已經(jīng)通過讀文檔,寫demo乌询,知道了pinia怎么用背蟆,今天,來研究下pinia是怎么實現(xiàn)的
程序入口
? ? 通過script中的build命令找到rollup配置文件
? ? 從打包配置可以看出其入口為src下的index
向vue注冊(初始化)
? ? 示例代碼
? ? 通過vue的插件機制劣砍,允許向整個應(yīng)用程序注冊全局共享的功能惧蛹,寫法一般固定為對象內(nèi)含install方法,由于pinia同時支持vue2和vue3刑枝,在入口處其暴漏了PiniaVuePlugin和createPinia來分別實現(xiàn)插件注冊
? ??PiniaVuePlugin
? ? ? ? 該函數(shù)利用mixins api向組件混入了beforeCreate周期鉤子香嗓,由于vue在組件實力化過程中會先讀取全局的mixins并會經(jīng)過一次配置合并過程,其中對生命周期的合并策略是數(shù)組的push装畅,故每一個組件實例初始化過程中都會callhook到beforeCreate
? ? ? ? 如下框紅所示靠娱,每一個組件實例中都將通過this訪問到pinia實例
? ??createPinia
? ? ? ? 與vue2不同的是,vue3中通過provide+inject的方式向子孫組件注入
定義掠兄、使用子模塊store? ??
? ??示例代碼
? ? 調(diào)用createPinia時像云,會向全局創(chuàng)建一個空對象作為根store,在組件使用時則對外提供了defineStore來定義組件的store蚂夕,這實際是在向根store做“add”操作
? ? 示例代碼
? ? 執(zhí)行定義函數(shù)調(diào)用后返回的useStore方法迅诬,會首先獲取到根store,接著將定義的本模塊的store設(shè)置到根store上并返回
store的創(chuàng)建過程
? ??示例代碼
? ? ? ? 承接上例
? ? 不管是option api形式還是setup形式婿牍,最終走的都是createSetupStore侈贷,在源碼層面對option形式做了次轉(zhuǎn)換
而store的創(chuàng)建過程其實分為兩部分:解析并掛載定義的store、為store裝飾api
? ??解析與掛載流程
? ??????裝飾api
? ? ? ? ? ? 這個比較簡單牍汹,就是將內(nèi)部的函數(shù)掛載到對象上并return出去即可
api相關(guān)
? ??$reset
? ? ? ? 該api是$patch的語法糖铐维,只不過傳遞的參數(shù)是初始的state函數(shù)的執(zhí)行結(jié)果
? ??$patch
? ? ? ? patch就是一次遞歸對value覆蓋的過程
? ??$subscribe
? ? ? ? 有點類似觀察者柬泽,當(dāng)調(diào)用subscribe時,會將當(dāng)前的狀態(tài)信息保存到subscriptions
? ? ????此時嫁蛇,只需要在調(diào)用修改store相關(guān)的api時锨并,拿到subscriptions的數(shù)組依次run一遍即可
插件機制
????通過pinia.use向pinia實例的_p屬性做緩存
? ? 接著,在創(chuàng)建store時將store傳遞給插件并執(zhí)行睬棚,如下extender即調(diào)用插件的初始化邏輯