Store中的Actions部分,用于定義操作屬性的方法,類似于組件中的methods部分,它與Getters都可以操作State屬性,但在定義方法時,Getters是對State屬性進行加工處理,再返回使用,屬于內部計算;Actions則是根據業務邏輯,操作State或Getters保存的值,方法中可以實現異步請求、調用任意的API,屬于邏輯層部分。
一、 構建和執行Actions中方法
Actions屬于Store中的一部分,因此,可以使用defineStore方法中Actions屬性來構建某個業務邏輯,例如:在上一小節10.3.1基礎上,構建兩個Actions中的方法,一個名稱為editCount,用于動態改變count的值,另一個名稱為addGrade,用于動態添加grade屬性的值,具體實現的代碼如下所示:
import { defineStore } from "pinia";
export const schStore = defineStore("sch_id", {state: () => {return {name: "精英學校",count: 1200,grade: ['小學', '初中']}},getters: {},actions: {editCount(val) {this.count = val;},addGrade(val) {this.grade.push(val);}}
})
在上述代碼的Actions屬性加粗部分中,分別定義了兩個方法editCount和addGrade,如果方法中需要傳入其他參數,可以直接在方法中定義形參,如val,如果需要訪問State中的屬性,可以通過this對象直接訪問屬性名即可,如this.count和this.grade。
Actions屬性構建完成后,如果需要在其他組件中調用,通常使用mapActions,將它的操作屬性映射成組件methods中的一部分,實現代碼如下所示:
<script>
import { mapState, mapActions } from 'pinia'
import { schStore } from "../../store/schStore";
export default {computed: {...mapState(schStore, ["grade", "count"])},methods: {...mapActions(schStore, ["editCount", "addGrade"])},mounted() {this.editCount(5);console.log(this.count);this.addGrade("高中");console.log(this.grade);}
}
</script>
在上述代碼的加粗部分中,先通過導入的mapActions函數,將Actions屬性映射成組件methods的成員,接下來,先調用editCount方法,由于傳入的實參為5,因此,第一次在控制臺輸出值為5;再調用addGrade方法,傳入實參為“高中”,因此,最后一次在控制臺輸出的內容為“小學”、“初中”、“高中”字樣。
二、執行異步請求
Actions屬性中還可以定義執行異步請求的方法,由于異步請求時,無法及時同步State屬性值,因此,通常將異步請求的方式使用async和await語句改成同步請求,例如:使用異步請求的方式,修改State中的name屬性值,代碼如下:
import { defineStore } from "pinia";
import axios from "axios";
export const schStore = defineStore("sch_id", {state: () => {return {name: "精英學校",count: 1200,grade: ['小學', '初中']}},getters: {},actions: {async ajaxEditName() {
const res = await axios
.get("http://rttop.cn/api/?day=1-1");this.name = res.data;}}
})
在上述加粗代碼中,為了實現異步請求,先導入axios模塊,然后在Actions屬性中定義一個名稱為ajaxEditName的方法,用于發送指定的請求地址,并將請求返回的結果更新name屬性值,該方法在組件中調用的代碼如下所示:
<script>
import { mapState, mapActions } from 'pinia'
import { schStore } from "../../store/schStore";
export default {computed: {...mapState(schStore, ["name"])},methods: {...mapActions(schStore, ["ajaxEditName"])},async mounted() {console.log(this.name)await this.ajaxEditName();console.log(this.name)}
}
</script>
在上述代碼的加粗部分中,先將ajaxEditName方法利用mapActions 函數映射成組件中methods的一個成員,然后在mounted事件中,先輸出name的屬性值,由于此時還沒有更新name值,因此,第一次輸出為name的初始值“精英學校”。
當使用await語句執行ajaxEditName方法時,必須等待異步請求完成,并更新name屬性值后才能執行下一條輸出語句,因此,當第二次執行輸出name屬性值時,已完成了數據和請求和更新,所以,第二次輸出的值為請求返回值“hello”。