掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
自從我開始使用Vue 3和組合API以來,我也嘗試使用 Pinea 作為狀態(tài)管理庫。如果是從是 vue2 和 vuex 過來的,就會覺得用起來差別還是很大的。

說實話,我對 Vuex 使用還是很不適應(yīng)。最初,有 "很多 "的模板代碼,只是讓 store 使用減少。不過,狀態(tài)管理確實給我們帶來了遍歷,特別是每當(dāng)我們有一小塊應(yīng)該跨組件共享的狀態(tài)時,就會更傾向于使用它。
我們先來看看 Vuex 和 Pinia 的整體設(shè)計以及它們之間的區(qū)別是什么。
下面是Vuex工作原理的官方圖示,剛開始學(xué)習(xí)時,一看就很懵,不過當(dāng)用過時開發(fā)過項目時,一看就就能懂了。
在 Vuex store(倉庫)中,有4個主要組件。
這只是一個包含實際狀態(tài)的對象。我們可以在開發(fā)工具中看到這個狀態(tài),如果想保留這個狀態(tài)用于緩存或其他目的,也可以保存這個對象。
Actions 是執(zhí)行異步任務(wù)的函數(shù)。它們是由關(guān)鍵字dispatch發(fā)起的。
Actions 通常會請求一個外部 API 或做一些其他的異步工作。它還負責(zé)調(diào)用適當(dāng)?shù)?nbsp;mutation 來實際改變狀態(tài)。這說明 actions 本身并沒有改變狀態(tài),而是 commit 變化,讓 mutation 來改變狀態(tài)。
Mutation 是唯一會真正同步改變狀態(tài)的函數(shù)。Mutations 使用關(guān)鍵字commit。
Getters可以被認為是計算過的屬性,應(yīng)該被用來從狀態(tài)中獲得一個修改過的響應(yīng)。
一個簡單的Vuex store 的例子如下所示:
const store = createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})在處理上述問題時,一個組件通常會調(diào)用dispatch?來啟動異步任務(wù)(比如從外部API中獲?。?。如果需要改變狀態(tài),比如一個簡單的計數(shù)器,可以調(diào)用 commit。
這意味著一個組件可以通過調(diào)用dispatch?或commit?來與 store 進行交互。我不知道你怎么想,但對我來說,這增加了一些心智負擔(dān),而我真的不需要。
在使用Vuex之前,我對 "commit" 和 "dispatch" 這兩個術(shù)語并不熟悉。由于這個原因,用它們來改變狀態(tài)對我來說并不直觀。對于一些人來說,這可能是不同的,但這讓我覺得使用 action? 或 mutation 都有點不舒服。
另外值得注意的是,使用Vuex,一個組件可以訪問整個 store,盡管在邏輯上將 Vuex store 分成不同的文件。
與Vuex相比,Pinia的工作原理圖如下:
整體架構(gòu)比 Vuex 更簡單,更容易理解。一個Pinia store 有3個主要組成部分:
與Vuex的定義一樣。
這里的 Actions 與Vuex中的 Actions 和 mutations 的工作相同。這些函數(shù)是改變狀態(tài)的唯一方式。如果想從外部API獲取數(shù)據(jù)并更新狀態(tài),也可以使用 actions 。
與Vuex設(shè)置的另一個區(qū)別是,Pinia actions 是普通函數(shù),心智負擔(dān)比 vuex 小很多。
getter 完全等同于 Store 狀態(tài)的計算屬性。
一個簡單的Pinia store 的例子如下所示:
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
actions: {
increment() {
this.counter++
}
},
})如果有多個模板, Vuex 一般采用 modules 方式,這就需要在 store/index.ts中將所有的 modules通過 creaeStore 注冊到 store 中,那么Pinia 就省去了這些麻煩,createPinia() 即可,不需要注冊 modules,沒有任何參數(shù),所以連 store/index.ts都可以不用了,直接在main.ts 中添加即可, 這一點會比Vuex簡潔很多。
import { createPinia } from 'pinia'
app.use(createPinia());
# main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')就目前而言,我想說Pinia更容易理解和使用。也許有一些東西可以讓Vuex在更大的項目中更好地擴展,但我還沒有遇到過這種情況。
對我來說,另一件重要的事情是,我們可以用正常的參數(shù)調(diào)用 actions 的正常方法。
Pinia還支持Vue 2和3的開箱即用,這使得遷移變得更加容易。
最后也在總結(jié)一下 Pinia 優(yōu)勢:

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流