????????Pinia 是 Vue 官方團隊成員專門開發的一個全新狀態管理庫,并且 Vue 的官方狀態管理庫已經更改為了 Pinia。 在 Vuex 官方倉庫中也介紹說可以把 Pinia 當成是不同名稱的 Vuex 5,這也意味不會再出 5 版本了。
優點
1. 更加輕量級,壓縮后提交只有1.6kb。
2. 完整的 TS 的支持,Pinia 源碼完全由 TS 編碼完成。
????????Pinia 在與 TS 一起使用時,具有可靠的類型判斷支持;Vuex 之前對 TS 的支持很不友好。
3. 移除 mutations,只剩下 state 、 actions 、 getters,在store內部直接使用this使用state里的數據。
????????一旦 store 被實例化,就可以直接在 store 上訪問 state、getters 和 actions 中定義的任何屬性;而在使用 Vuex 的時候,更改狀態需要糾結選取 mutation 還是 action。
4. 不再有 Vuex 里多個 modules 的嵌套結構,可以定義多個 store 并靈活使用。
5. 不會再有module的命名空間的概念,不需要記住他們的復雜關系。
6. 支持服務端渲染(SSR)。
7. 更友好的代碼分割機制。
8. 提供了 Pinia 狀態持久化。配置 | Pinia Plugin Persistedstate
舉例說明
針對第4點
????????Pinia版本:假設我們有一個購物車應用,需要管理用戶信息和購物車商品信息,可以用兩個 Store 來實現。
// userStore.js
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {state: () => ({name: '',age: 0,}),actions: {updateName(newName) {this.name = newName;},},
});// cartStore.js
import { defineStore } from 'pinia';
export const useCartStore = defineStore('cart', {state: () => ({items: [],}),actions: {addItem(item) {this.items.push(item);},},
});
? ? ? ? Vuex版本:在組件中,通過 this.$store
來訪問狀態,需要通過命名空間來區分模塊,例如 this.$store.state.user.name
或 this.$store.commit('cart/addItem', item)
。
// store.js
import { createStore } from 'vuex';
export default createStore({modules: {// 用戶user: {state: {name: '',age: 0,},mutations: {updateName(state, newName) {state.name = newName;},},},// 購物車cart: {state: {items: [],},mutations: {addItem(state, item) {state.items.push(item);},},},},
});
針對第5點
????????Vuex 中,如果沒有命名空間,多個模塊有相同名稱的方法,如模塊A和模塊B都有updateName
,使用起來會沖突,因為 Vuex 不知道要調用哪個模塊的 updateName
。
// 模塊 A
mutations: {updateName(state, newName) {state.name = newName;},
}// 模塊 B
mutations: {updateName(state, newName) {state.name = newName;},
}
????????通過命名空間namespaced: true,可以將每個模塊的作用域限制在模塊內部,避免沖突。
// 模塊 A
namespaced: true,
mutations: {updateName(state, newName) {state.name = newName;},
}// 模塊 B
namespaced: true,
mutations: {updateName(state, newName) {state.name = newName;},
}// 組件中使用
this.$store.commit('moduleA/updateName', 'John');
this.$store.commit('moduleB/updateName', 'Jane');
????????當然,在 pinia 中沒有模塊化的概念了,就更不存在需要使用命名空間了。