為什么有些 Vue3 項(xiàng)目已經(jīng)開(kāi)始棄用 Pinia 了?
真的需要 Pinia 嗎?
最近在想一個(gè)問(wèn)題:在 Vue3 項(xiàng)目中,進(jìn)行狀態(tài)管理的時(shí)候,我們真的需要 Pinia 嗎?
其實(shí)我們可以反過(guò)來(lái)想一個(gè)問(wèn)題:沒(méi)有 Pinia,我們能做狀態(tài)管理嗎?
答案是:可以?。?!
ref、reactive
Vue3 的一些 API 對(duì)比 React 的好處就是,這些 API 并不一定需要在組件中去聲明。
就比如你想要做局部狀態(tài)管理的時(shí)候,可以直接使用 reactive、ref 這類 API 來(lái)完成。
圖片
圖片
圖片
這樣能達(dá)到局部狀態(tài)管理,多組件共用同一個(gè)狀態(tài)的效果,請(qǐng)看下圖:
圖片
effectScope
Vue3 有一個(gè)超級(jí)冷門的 API 叫 effectScope ,這個(gè) API 非常強(qiáng)大,但是很多人都不知道它。
當(dāng)然,既然很少人知道它,那自然就很少人知道,Pinia 的底層原理就是依賴了 effectScope。
圖片
既然 Pinia 是通過(guò)effectScope來(lái)實(shí)現(xiàn)的,那么,我們自然也可以直接使用這個(gè) API 來(lái)做狀態(tài)管理!
其實(shí)已經(jīng)有人做過(guò)這件事了,就比如 vueuse 中的。
圖片
我們可以直接用這個(gè) Hooks 來(lái)進(jìn)行狀態(tài)管理,如果是使用 effectScope 來(lái)進(jìn)行管理的話,狀態(tài)就不需要寫在 Hooks 外部了,因?yàn)?effectScope 內(nèi)部邏輯只會(huì)執(zhí)行一次,無(wú)論你調(diào)用多少次。
圖片
圖片
圖片
利用 effectScope 也能達(dá)到組件之間共享狀態(tài)!
圖片
那還需要 Pinia 嗎?
結(jié)構(gòu)分明
我覺(jué)得 Pinia 還是有他的好處的,好處就是:讓我們少寫一些代碼,并且代碼更加分明。
比如下面這個(gè)例子:
- state: 定義狀態(tài)
- getter: 定義計(jì)算變量
- action: 定義修改方法
結(jié)構(gòu)很分明:
圖片
監(jiān)聽(tīng) state
Pinia 還提供了 $subscribe 來(lái)監(jiān)聽(tīng)整個(gè)狀態(tài),我們也可以利用這個(gè)方法來(lái)做持久化存儲(chǔ)。
插件機(jī)制
Pinia 提供了插件機(jī)制,可以讓你去拓展 Pinia 的功能,以下是你可以擴(kuò)展的內(nèi)容:
- 為 store 添加新的屬性
- 定義 store 時(shí)增加新的選項(xiàng)
- 為 store 增加新的方法
- 包裝現(xiàn)有的方法
- 改變甚至取消 action
- 實(shí)現(xiàn)副作用,如本地存儲(chǔ)
- 僅應(yīng)用插件于特定 store
比如舉個(gè)小例子,給所有狀態(tài)管理都加一個(gè)屬性變量。
Pinia 著名的持久化插件pinia-plugin-persistedstate就是利用了 Pinia 的插件機(jī)制。
他的核心代碼其實(shí)很少,就是利用插件機(jī)制,使用$subscribe去監(jiān)聽(tīng)每一個(gè)狀態(tài)管理的變化,然后進(jìn)行持久化存儲(chǔ)!