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
相关推荐
Rysxt_21 分钟前
UniApp uni_modules 文件夹详细教程
开发语言·javascript·ecmascript
霍理迪32 分钟前
CSS盒模型布局规则
前端·javascript·css
林恒smileZAZ44 分钟前
使用自定义API接入OpenAI CodeX配置教程
javascript·codex·ai对接
千寻girling1 小时前
面试官: “ 说一下 JS 中什么是事件循环 ? ”
前端·javascript
程序员龙语1 小时前
CSS 高级选择器应用
前端·css
Cassie燁1 小时前
el-table源码解读2-2——createStore()初始化方法
前端·javascript·vue.js
程序员修心1 小时前
CSS文本样式全解析:11个核心属性详解
前端·css
旧梦吟1 小时前
脚本网站 开源项目
前端·web安全·网络安全·css3·html5
我有一棵树1 小时前
解决 highlight.js 不支持语言的方法
开发语言·javascript·ecmascript
北极糊的狐1 小时前
按钮绑定事件达成跳转效果并将树结构id带入子页面形成参数完成查询功能并将返回的数据渲染到页面上2022.5.29
前端·javascript·vue.js