仿牌做獨立網(wǎng)站可靠嗎全球搜索
集中式狀態(tài)管理工具—pinia
vue3中使用pinia作為集中式狀態(tài)管理工具,替代vue2中的vuex。
pinia文檔可參考: https://pinia.web3doc.top/introduction.html
1.項目集成pinia
安裝pinia依賴:
npm install pinia
在main.ts中引入pinia
import { createApp } from 'vue'
import App from './App.vue'// 從pinia庫引入createPinia方法
import { createPinia } from 'pinia'//調(diào)用createPinia方法創(chuàng)建pinia對象,設(shè)置到APP中
createApp(App).use(createPinia()).mount('#app')
2.定義store
pina提供了defineStore方法創(chuàng)建store,store作為集中式狀態(tài)管理的實體,可被任意組件讀取/寫入數(shù)據(jù)。定義的store一般放在src/stores目錄下。
import {defineStore} from 'pinia'// 定義并暴露一個store
export const useXXXStore = defineStore('XXX', {// 配置信息
})
defineStore方法接收兩個參數(shù),store的唯一標(biāo)識符和store的配置對象。其中,store配置對象中可以包含 state函數(shù)、actions對象、getters對象。
state中可以定義狀態(tài)信息,getters基于state定義計算屬性,actions中定義state相關(guān)的操作方法。以下結(jié)合案例進(jìn)行說明:
// src/stores/clock.tsimport { defineStore } from 'pinia'export const useClockStore = defineStore('clock', {state: () => {return { hourHand: 0,minuteHand: 0,secondHand: 0}},getters:{time() {return this.hourHand +"時: "+this.minuteHand +"分: "+this.secondHand +"秒";}},actions: {increHour() {this.hourHand++;},getTime() {return this.time;}},
})
state中包含3個狀態(tài)屬性:hourHand和minuteHand和secondHand,初始值和默認(rèn)值為0;
getters中定義了一個獲取時間的方法time():根據(jù)狀態(tài)值計算出時間信息;
actions中定義了一個修改狀態(tài)變量的方法和一個獲取計算屬性的方法。
3.使用store
在任意組件中,可以引入和使用章節(jié)2中定義的store,方式如下:
import { useClockStore } from '@/stores/clock'
const clockStore = useClockStore()
得到clockStore這個store后,可以直接在template或者script腳本中通過屬性名獲取state的屬性(含計算屬性):
clockStore.time
clockStore.hourHand
clockStore.minuteHand
clockStore.secondHand
也可以調(diào)用store在actions中定義的方法:
clockStore.increHour()
clockStore.getTime()
使用章節(jié)2中定義的clock.ts完整的案例組件如下所示:
<template>
<div><p><span>{{clockStore.hourHand}}</span><span>:</span><span>{{clockStore.minuteHand}}</span><span>:</span><span>{{clockStore.secondHand}}</span></p><button @click="addHour">addHourBtn</button><button @click="showTime">showTimeBtn</button></div>
</template><script lang="ts" setup>import { useClockStore } from "@/stores/clock.ts";const clockStore = useClockStore();function addHour() {clockStore.increHour();}function showTime() {alert(clockStore.time);}
</script>
此時,clockStore中的狀態(tài)屬性和計算屬性作為響應(yīng)式數(shù)據(jù)。
除了上述通過store中actions定義的方法外,還可通過以下方式直接修改狀態(tài)值:
clockStore.hourHand=12// 批量修改
clockStore.$patch({hourHand:12,minuteHand:30,secondHand:0
})
4.響應(yīng)式狀態(tài)提取
章節(jié)3中提到過clockStore對象的狀態(tài)屬性和計算屬性作為響應(yīng)式數(shù)據(jù),且可以直接操作clockStore對象的屬性。
但是如果將其進(jìn)行提取,則會失去響應(yīng)式:
// clockStore.hourHand為響應(yīng)式,修改為12后,頁面會發(fā)生變化
clockStore.hourHand=12// hour不是響應(yīng)式對象
let hour = clockStore.hourHand
可以通過pinia的storeToRefs為其提供了一個解決方案:
import { storeToRefs } from 'pinia'// 根據(jù)狀態(tài)名稱進(jìn)行提取
const {hourHand, minuteHand,secondHand} = storeToRefs(clockStore)
hourHand.value = hourHand.value +100;
此時,可以在template結(jié)構(gòu)中直接使用hourHand, minuteHand,secondHand,而不需要再使用clockStore.hourHand, clockStore.minuteHand,clockStore.secondHand.
解析出的數(shù)據(jù)為ObjectRefImpl類型,因此在script腳本中,修改和獲取值時需要使用.value進(jìn)行值的提取。
5.訂閱store狀態(tài)變化
可以通過store對象的$subscribe方法監(jiān)聽狀態(tài)的變化,使用如下所示:
import { useClockStore } from "@/stores/clock.ts";
const clockStore = useClockStore();clockStore.$subscribe((mutate, state)=>{// 定制操作console.log(mutate)console.log(state)
})
mutate中包含了發(fā)生變化的屬性key以及變化前后的值;state為更新后的狀態(tài)對象。
mutate參數(shù)打印信息如下:
{storeId: "clockStore", type: "direct", events:{key: "hourHand", oldValue: 0, newValue: 1}}
state參數(shù)打印信息如下:
Proxy {hourHand: 1, minuteHand: 0, secondHand: 0}