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”。