SoFunction
Updated on 2025-04-06

The difference between mutations and actions in Vuex and description

mutation

We know that when using vuex to manage project status, we can only use commit to commit to make changes to the status in the store

Mutations in Vuex are very similar to events: each mutation has a string of event type (type) and a callback function (handler). This callback function is where we actually make the state change, and it will accept state as the first parameter:

const store = new ({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // Change status      ++
    }
  }
})
//You cannot call a mutation handler directly.  This option is more like event registration: "When a mutation of type increment is triggered, this function is called." To wake up a mutation handler, you need to call the method with the corresponding type:('increment')   

Mutation must be a synchronous function

mutations: {
  someMutation (state) {
    (() => {
      ++
    })
  }
}

We pay attention to the above code, which adds asynchronous processing functions to the mutation.

In fact, mutation can be used normally, but when we debug in daily development, we need to check the mutation log in devtool.

Theoretically, it is a step for mutation and a step for devtool to record, but adding asynchronous functions to mutation will cause our devtool to fail, because devtool does not know when and where to call the asynchronous functions in your

Action

Action is similar to mutation, the difference is:

Action submits mutation, not a direct change of state.

Action can contain any asynchronous operation.

const store = new ({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      ++
    }
  },
  actions: {
    increment (context) {
      ('increment')
    }
  }
})

The Action function accepts a context object with the same method and properties as the store instance, so you can call submit a mutation, or get state and getters via and .

In practice, we often use ES2015's parameter deconstruction (opens new window) to simplify the code (especially when we need to call commit many times):

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

In the actual developed store file

// src/store/

import Vue from 'vue';
import Vuex from '@/vuex';

(Vuex);

const store = new ({
  state: {
    num: 10
  },
  getters: {
    getPrice(state) {
      return  * 10
    }
  },
  // Synchronous update statusimport { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'

const user = {
  state: {
    token: getToken(),
    name: '',
    avatar: '',
    roles: [],
    permissions: []
  },
//Synchronous method  mutations: {
    SET_TOKEN: (state, token) => {
       = token
    },
    SET_NAME: (state, name) => {
       = name
    },
    SET_AVATAR: (state, avatar) => {
       = avatar
    },
    SET_ROLES: (state, roles) => {
       = roles
    },
    SET_PERMISSIONS: (state, permissions) => {
       = permissions
    }
  },
//Async method  actions: {
    // Login (use single sign-in here will be invalid)    Login({ commit }, userInfo) {
      const loginType = 
      const tentantCode = 
      const username = ()
      const password = 
      const code = 
      const uuid = 
      return new Promise((resolve, reject) => {
        login(loginType, tentantCode, username, password, code, uuid).then(res => {
          setToken()
          commit('SET_TOKEN', )
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

    // Get user information    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo().then(res => {
          if (
            && 
            > 0) { // Verify that the returned roles is a non-empty array            commit('SET_ROLES', )
            commit('SET_PERMISSIONS', )
          } else {
            commit('SET_ROLES', ['ROLE_DEFAULT'])
          }
          commit('SET_NAME', 
          )
          commit('SET_AVATAR', )
          resolve(res)
        }).catch(error => {
          reject(error)
        })
      })
    },

    // Exit the system    LogOut({ commit, state }) {
      return new Promise((resolve, reject) => {
        logout().then(() => {
          commit('SET_TOKEN', '')
          commit('SET_ROLES', [])
          commit('SET_PERMISSIONS', [])
          removeToken()
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

    // Front-end logout    FedLogOut({ commit }) {
      return new Promise(resolve => {
        commit('SET_TOKEN', '')
        removeToken()
        resolve()
      })
    }
  }
}

export default user

For example, when we log in, we need to trigger the method in the store.

<template>
  <div>Single sign-in page</div>
</template>

<script>
import {
  doLoginByTicket,
  getInfo,
  isLogin,
  getSsoAuthUrl,
  getRouter,
} from "../api/login";
import { getToken, setToken } from "@/utils/auth";
export default {
  name: "Screenfull",
  data() {
    return {};
  },
  created() {
    ();
  },

  methods: {
    checkIsLogin() {
      isLogin().then((res) => {
        if ( == true) {
          //Get user information;          ("isLogin", res);
          // this.$("/");
        } else {
          //Get the complete url that is requested to enter          let url = ;
          if (("ticket=") < 0) {
            //If there is no ticket            getSsoAuthUrl({ clientLoginUrl: url }).then((res) => {
               = ;
            });
            return;
          }
          let tstr = url
            .substring(("?") + 1)
            .split("=")[1]
            .split("#")[0]; //First intercept the parameter part of the url? and divide it into parameter array according to &          doLoginByTicket({ ticket: tstr }).then((res) => {
            if ( == 200) {
              setToken();
              getInfo().then((res) => {
                if () {
                //Trigger mutations synchronization method                  this.$("SET_ROLES", ["admin"]);
                  this.$("SET_PERMISSIONS", ["*:*:*"]);
                } else {
                  commit("SET_ROLES", ["ROLE_DEFAULT"]);
                }
                this.$("SET_NAME", );
              });
              getRouter().then(() => {
                //Trigger actions asynchronous method                this.$("GenerateRoutes");
                ();
              });
            } else {
              ("Check the bill failed");
            }
          });
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped></style>

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.