Vuex中commit和dispatch的核心区别

在 Vuex 中,commitdispatch 是调用 Vuex 核心方法的两个关键 API,核心区别在于作用目标、执行方式(同步 / 异步)和使用场景,以下区别:

一、核心结论(重点)

特性 commit dispatch
作用目标 调用 mutations 中的方法 调用 actions 中的方法
执行方式 同步执行(必须同步) 可同步 / 异步执行(主要用于异步)
能否直接改 state 间接改(通过 mutations 改,唯一合法方式) 不能直接改,需通过 commit 调用 mutations
核心用途 同步修改 Vuex 状态 处理异步逻辑(如接口请求),再同步改状态
调用语法 this.$store.commit('方法名', 参数) this.$store.dispatch('方法名', 参数)
辅助函数 mapMutations 对应 commit mapActions 对应 dispatch

二、逐点拆解 + 代码

1. commit:提交 mutation(同步修改状态)

commit 的核心是触发 mutations 中的同步方法 ,而 mutations 是 Vuex 中唯一允许修改 state 的地方,且必须是同步函数(异步会导致 Vuex 无法追踪状态变化)。

用法示例:

javascript 复制代码
// store/index.js
const store = new Vuex.Store({
  state: {
    token: ''
  },
  // mutations:仅负责同步修改state,无副作用(如异步请求)
  mutations: {
    // state:当前模块的state;val:commit时传入的参数
    setToken(state, val) {
      state.token = val; // 唯一合法的state修改方式
    }
  }
})

// 组件中调用(commit触发mutation)
export default {
  methods: {
    handleSetToken() {
      // 方式1:直接commit
      this.$store.commit('setToken', 'abc123'); 
      // 方式2:辅助函数mapMutations(语法糖)
      // import { mapMutations } from 'vuex'
      // methods: { ...mapMutations(['setToken']) }
      // this.setToken('abc123');
    }
  }
}

关键规则:

  • mutations 必须是同步函数 (如果写异步,比如 setTimeout,Vuex 无法追踪 state 何时被修改,DevTools 也无法正确记录状态变化);
  • commit 是 "同步提交",调用后立即执行 mutation 并修改 state。
2. dispatch:分发 action(处理异步逻辑)

dispatch 的核心是触发 actions 中的方法actions 是 Vuex 中处理异步逻辑(如接口请求、定时器) 的唯一合法层,本身不允许直接修改 state,必须通过 commit 调用 mutations 来修改。

用法示例:

javascript 复制代码
// store/index.js
import axios from 'axios'
const store = new Vuex.Store({
  state: {
    token: ''
  },
  mutations: {
    setToken(state, val) {
      state.token = val;
    }
  },
  // actions:处理异步逻辑,无权限直接改state
  actions: {
    // context:上下文对象(包含commit、dispatch、state等);userInfo:dispatch传入的参数
    async login(context, userInfo) {
      // 异步操作:调用登录接口
      const res = await axios.post('/api/login', userInfo);
      // 异步完成后,通过commit触发mutation修改state
      context.commit('setToken', res.data.token);
      
      // 简写:解构context,直接用commit
      // async login({ commit }, userInfo) {
      //   const res = await axios.post('/api/login', userInfo);
      //   commit('setToken', res.data.token);
      // }
    }
  }
})

// 组件中调用(dispatch触发action)
export default {
  methods: {
    async handleLogin() {
      // 方式1:直接dispatch
      await this.$store.dispatch('login', {
        username: '张三',
        password: '123456'
      });
      
      // 方式2:辅助函数mapActions(语法糖)
      // import { mapActions } from 'vuex'
      // methods: { ...mapActions(['login']) }
      // await this.login({ username: '张三', password: '123456' });
    }
  }
}

关键规则:

  • actions 可以包含任意异步操作(axios 请求、setTimeout、Promise 等);
  • dispatch 支持异步执行(返回 Promise),组件中可通过 await 等待异步逻辑完成;
  • actions 绝对不能直接修改 state(比如 context.state.token = val),这是 Vuex 的强制规范,会导致状态管理混乱。

三、核心区别的通俗类比

把 Vuex 比作 "公司仓库":

  • state = 仓库里的货物;
  • mutations = 仓库管理员(只能同步干活,比如 "把 A 货物放到货架",指令下达后立即执行);
  • commit = 给管理员下指令(同步指令,下完就执行);
  • actions = 采购部门(可以先去供应商拿货(异步请求),拿到货后再通知管理员上架);
  • dispatch = 给采购部门下任务(可异步,等采购完成后再同步上架)。

四、常见误区

  1. commit 处理异步逻辑 :❌ 错误:在 mutations 中写 setTimeout/axios 请求,会导致 Vuex 无法追踪 state 变化,DevTools 状态错乱;✅ 正确:异步逻辑全放在 actions 中,通过 dispatch 调用,异步完成后再 commit 修改 state。

  2. dispatch 直接改 state :❌ 错误:context.state.token = val(跳过 mutations);✅ 正确:context.commit('setToken', val)(必须通过 mutations 修改)。

五、总结记忆

  • commit → 同步 → 调 mutations → 改 state(直接的 "状态修改指令");
  • dispatch → 异步 → 调 actions → 再 commit → 改 state(带异步逻辑的 "状态修改前置任务");
  • 一句话:同步改状态用 commit,异步逻辑后改状态用 dispatch
相关推荐
草字1 小时前
css 按钮的脉冲光环动画,强调动画。
前端·css
BD_Marathon1 小时前
【JavaWeb】CSS_三大选择器
前端·css
jump6801 小时前
柯里化
前端
NeoInfra1 小时前
全面解读ThinkPHP 5.0:现代PHP框架的架构演进与安全实践
前端
一 乐1 小时前
宠物店管理|基于Java+vue的宠物猫店管理管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
BD_Marathon1 小时前
【JavaWeb】JS_数据类型和变量
开发语言·javascript·ecmascript
qq_229058011 小时前
react的3中请求
前端·react.js·前端框架
渴望成为python大神的前端小菜鸟1 小时前
VUE 面试题
前端·javascript·vue.js·面试题
想要成为糕糕手1 小时前
深入理解 JavaScript 中的 “this”:从自由变量到绑定规则
前端·javascript