在文章开始之前,再次强调一句:Vuex会把getter mutations action不管是在模块定义的还是在根级别定义的 都会注册在全局
官网API地址:https://vuex.vuejs.org/zh/guide/actions.html
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
下面以一个包含异步操作的例子来说明Action的应用场景:
代码目录结构:
actions.js:
import { getAppName } from "@/api/app"; const actions = { //ES6解构赋值 相当于:updateAppName(paramsObj) {const commit=paramsObj.commit} // updateAppName({ commit }) { // } /* *commit: 提交一个 mutation *state:指代当前store实例的state *rootState:指代根store实例的state *dispatch:可以分发actions中的其他方法 */ updateAppName({ commit, state, rootState, dispatch }) { getAppName() .then(res => { //ES6解构赋值 const { info } = res; commit("SET_APP_NAME", info); }) .catch(err => { console.log(err); }); } //调用Promise也可以使用ES8的async await 代码更简洁 /*async updateAppName({ commit }) { try { const { info } = await getAppName(); commit("SET_APP_NAME", info); } catch (error) { console.log(error); } }*/ }; export default actions;
app.js:
export const getAppName = () => { return new Promise((resolve, reject) => { const err = null; setTimeout(() => { if (!err) { resolve({ code: 200, info: { appName: "WeChat" } }); } else { reject(err); } }, 1000); }); };
mutations.js:
import vue from 'vue' const mutations = { SET_APP_NAME(state, params) { //若params是对象格式 state.appName = params.appName; //若params是字符串格式 //state.appName = params; }, SET_APP_VERSION(state) { debugger vue.set(state, 'appVersion', 'v100.0') //state.appVersion = 'v2.0' } } export default mutations;
store.vue:
<template> <div> <a-input :value="inputValue" @input="handlerInput"></a-input> <p>{{ inputValue }} -> lastLetter is {{ inputValueLastLetter }}</p> <p>appName: {{ appName }}, appNameWithVersion : {{ appNameWithVersion }}</p> <p>userName : {{ userName }}, firstLetter is : {{ firstLetter }}</p> <button @click="handleChangeAppName">修改appName和user.js中的userName</button> <p>动态给state增加appVersion: {{ appVersion }}</p> <button @click="handleActionChangeAppName">通过Action修改appName</button> </div> </template> <script> import AInput from "_c/AInput.vue"; import AShow from "_c/AShow.vue"; //变量的解构赋值 import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; import { stat } from "fs"; export default { name: "store", data() { return { inputValue: "" }; }, components: { AInput: AInput, AShow: AShow }, computed: { //ES6展开操作符 mapState展开会形成一个对象 使用对象展开运算符将此对象混入到外部对象中 ...mapState({ appName: state => state.appName, appVersion: state => state.appVersion, userName: state => state.user.userName }), // 使用对象展开运算符将 getter 混入 computed 对象中 // ...mapGetters(["appNameWithVersion"]), appNameWithVersion() { //通过属性访问getters,Getter 会暴露为 store.getters 对象,可以以属性的形式访问这些值: return this.$store.getters.appNameWithVersion; }, ...mapGetters(["firstLetter"]), inputValueLastLetter() { return this.inputValue.substr(-1, 1); } }, methods: { handlerInput(val) { this.inputValue = val; }, // ...mapMutations([ "SET_USER_NAME", //将 `this.SET_USER_NAME()` 映射为 `this.$store.commit('SET_USER_NAME')` "SET_APP_NAME" //将 `this.SET_APP_NAME()` 映射为 `this.$store.commit('SET_APP_NAME')` ]), ...mapActions([ "updateAppName"//将 `this.updateAppName()` 映射为 `this.$store.dispatch('updateAppName')` ]), handleChangeAppName() { this.SET_APP_NAME({ appName: "newAppName" }); this.SET_USER_NAME({ userName: "shuyujie" }); this.$store.commit("SET_APP_VERSION"); }, handleActionChangeAppName() { //第一种调用Action的方法 //this.$store.dispatch('updateAppName') //第二种调用Action的方法 this.updateAppName(); } } }; </script>
效果图:
从图中也可以看出 ,Action 提交的是 mutation,而不是直接变更状态。