参考文档:https://vuex.vuejs.org/zh/guide/

actions功能与mutations相近,区别主要有以下两点:

  1. actions不能直接改变state,只能通过调用mutation来改变state(mutations不能调用mutations,但是actions可以);
  2. mutations只能执行同步操作,而actions可以执行异步操作。

如果我们把state、getters、mutations和actions一股脑全部定义在一个文件里,会导致Vuex的定义文件非常臃肿,因此在下面的例子里我们尝试把actions拆出来。首先需要单独定义actions(新增文件路径为src\store\action.js),代码如下:

export default {
    // context对象中包含state、commit和dispatch,分别对应Vuex中的state、执行mutations方法和执行actions方法
    action1: context => {
        setTimeout(() => {
            context.commit("mutation1");
        }, 1000);
    }
};

然后在Vuex中引入并声明actions(修改文件路径为src\store\index.js),代码如下:

import Vue from "vue";
import Vuex from "vuex";

import action from "./action";

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        param1: "state param"
    },
    getters: {
        param2: state => {
            return `new ${state.param1}`;
        },
        // 在getters中可以使用其他getters
        param3: (state, getters) => {
            return `another ${getters.param2}`;
        },
        // getter支持返回一个函数
        param4: state => index => {
            return state.paramArray[index];
        }
    },
    // mutations不支持相互调用(如下面的mutation1不能调用mutation2)
    mutations: {
        mutation1: state => {
            // 在mutations的回调函数内可以修改state的值
            state.param1 += " add something";
        },
        // mutations支持传递参数(第二个参数)
        mutation2: (state, addString) => {
            state.param1 += addString;
        }
    },
    actions: action
});

export default store;

接下来在组件中引入并调用(新增文件路径为src\components\componentG.vue),代码如下:

<template>
    <div>
        <span>actions和mapActions用法</span>
        <br />
        <span>state in vuex:{{param1}}</span>
        <br />
        <button @click="action1()">mapActions</button>
    </div>
</template>

<script>
import { mapState, mapActions } from "vuex";
export default {
    name: "component-g",
    computed: {
        ...mapState(["param1"])
    },
    methods: {
        ...mapActions(["action1"])
        // action1() {
        //     // 通过this.$store.dispatch("actions方法名")的方式可以调用actions,当然,定义...mapActions(["action1"])然后直接写this.action1();肯定更方便
        //     this.$store.dispatch("action1");
        // }
    }
};
</script>

<style scoped>
</style>

最后引用上面创建的component-g查看效果(修改文件路径为src\main.js),代码如下:

import Vue from 'vue'
import store from './store'
import ComponentA from './components/ComponentA.vue'
import ComponentB from './components/ComponentB.vue'
import ComponentC from './components/ComponentC.vue'
import ComponentD from './components/ComponentD.vue'
import ComponentE from './components/ComponentE.vue'
import ComponentF from './components/ComponentF.vue'
import ComponentG from './components/ComponentG.vue'

new Vue({
    el: '#app',
    store,
    components: { ComponentA, ComponentB, ComponentC, ComponentD, ComponentE, ComponentF, ComponentG },
    template: '<div><component-a></component-a><component-b></component-b><component-c></component-c><component-d></component-d><component-e></component-e><component-f></component-f><component-g></component-g></div>'
});

运行后点击mapActions按钮可以看到一秒后state发生了变化,这表示actions可以以异步的方式来调用mutations。

Logo

前往低代码交流专区

更多推荐