Pinia 快速上手運用
相比于Vuex 4.X而言Pinia可以很好的區分相應的Hooks不必要像Vuex 一樣先調用useStore獲取我們的Store。
單獨的Hooks可以很好的區分我們的模塊和業務,不必像Vuex中module那樣調用復雜。
同時去掉了Vuex Mutations屬性,正常開發中其實這個屬性非常雞肋。
兩者相比,明顯Pinia更適合Vue3的setup,同時更好兼容TypeScript。
前言:
在使用Pinia前需要使用對應的vue app 安裝。
import { createPinia } from 'pinia'// vue app創建流程
app.use(createPinia()); // 安裝pinia
一、聲明一個Store
1 import {defineStore} from 'pinia'; 2 3 export const useUserInfo = defineStore('userInfo', { 4 state: () => ({ 5 name: 'lisi', 6 age: 18, 7 }), 8 getters: { 9 userName: (state) => state.name, 10 getAuthCode(state) { // 此使用方式將失去本身緩存能力 單純作函數使用 11 return (id) => [Code]; 12 } 13 }, 14 actions: { 15 setName(newName) { 16 this.name = newName; 17 } 18 } 19 });
可以看到在我們聲明的actions中可以直接調用this.xxx 即可調用到我們的state中聲明的屬性,相比vuex 4.x 需要調用 commit 還是比較友好的。
建議還是使用actions
同時我們想要清除掉當前的Store可以接收其返回值并調用$reset函數。
<script setup lang="ts"> import { useUserInfo } from './store'; const userInfoStore = useUserInfo(); // 重置狀態 userInfoStore.$reset(); // 改變狀態 userInfoStore.$patch({name: "張三"}); // 可以傳入部分的state屬性,會根據傳入屬性更新state,但是此種修改比較低能。 userInfoStore.$patch((state) => { state.name = 'wangwu'; }); // 方便修改和精確調整其接受函數回調提供修改state,因為其屬性為響應式的所以可以直接修改。
// 替換整個state userInfoStore.$state = {sex: 1}; // 此方式就可以替換掉當前的store的state </script>
二、調用其他的Store
其實調用其他的store非常簡單,可能你已經想到了!沒錯,就是導入我們聲明的useUserInfo;
import {defineStore} from 'pinia';
import { useUserInfo } './store';
export const useUserAuthCode = defineStore('userAuthCodes', {
state: () => {
userCodes: [],
},
actions: {
getUserAuthCodeById(state) {
const userStore = useUserInfo(); // 獲取useInfoStore,getters中也是如此使用
// todo 異步請求
this.userCodes = []; // 獲取到的數據
}
}
});
三、訂閱監聽
(1)State的監聽 store.$subscribe(callback, options);
<script steup> import { useUserInfo } from './store'; const userInfoStore = useUserInfo(); userInfoStore.$subscribe((mutation, state) => { // import { MutationType } from 'pinia' mutation.type // 'direct' | 'patch object' | 'patch function' // 與 userInfoStore.$id 相同 mutation.storeId // 'cart' // 僅適用于 mutation.type === 'patch object' mutation.payload // 補丁對象傳遞給 to userInfoStore.$patch() // 做自己需要監聽的事情 }); </script>
監聽事件默認綁定到當前組件實例上,組件卸載會自動移除,想要保留其狀態需要設置它的options = { detatched: true }。
其特點與watch非常類似,但是$subscribe只在 patches 之后觸發一次。
(2) 監聽actions store.$onActions(callback, boolean);
import { useUserInfo } form './store';
const userInfoStore = useUserInfo();
const unUserInfoSubscribe = userInfoStore.$onAction(({
name, // action 的名字,
store, // store 實例
args, // 調用這個 action 的參數
after, // 在這個 action 執行完畢之后,執行這個函數
onError, // 在這個 action 拋出異常的時候,執行這個函數
}) => {
// 如果 action 成功并且完全運行后,after 將觸發。
// 它將等待任何返回的 promise
// 如果 action 拋出或返回 Promise.reject ,onError 將觸發
}, true); // 第二位參數標識當前組件卸載后保留狀態
unUserInfoSubscribe(); // 卸載監聽
監聽事件默認綁定到當前組件實例上,組件卸載會自動移除。
四、非setup的使用
import { mapState, mapActions } from 'pinia'
import { useUserInfo } from '../store'
export default {
computed: {
// state | getters
// 允許訪問組件內的 this.userName
// 與從 store.userName中讀取相同
...mapState(useUserInfo , ['userName'])
// 與上面相同,但將其注冊為 this.name
...mapState(useUserInfo , {
name: 'userName',
// 您還可以編寫一個訪問 store 的函數
userAge: store => store.userName,
})
},
methods: {
...mapActions(useUserInfo, ['setName']),
...mapActions(useUserInfo, {
setUserName: 'setName',
}),
},
};
兩個mapXXX都需要兩個參數,第一個是我們定義的Store函數,第二個參數可以是數組和對象,數組中聲明對應的state或actions中存在key名稱,對象則可以聲明自定義的key:對應聲明的Key。
mapState中對象類型options還可以聲明函數,接收一個store可以任意訪問state中的參數。大致與vuex 3.x版本差不多。
tips: Pinia肯定也是擁有組合式的寫法,語法和我們自定義Hooks是一樣的,還有嵌套的Store,它的書寫方式參考Getters,Actions的共享狀態。

浙公網安備 33010602011771號