在 Vuex 中,commit 和 dispatch 是调用 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= 给采购部门下任务(可异步,等采购完成后再同步上架)。
四、常见误区
用
commit处理异步逻辑 :❌ 错误:在mutations中写setTimeout/axios 请求,会导致 Vuex 无法追踪 state 变化,DevTools 状态错乱;✅ 正确:异步逻辑全放在actions中,通过dispatch调用,异步完成后再commit修改 state。用
dispatch直接改state:❌ 错误:context.state.token = val(跳过 mutations);✅ 正确:context.commit('setToken', val)(必须通过 mutations 修改)。
五、总结记忆
commit→ 同步 → 调 mutations → 改 state(直接的 "状态修改指令");dispatch→ 异步 → 调 actions → 再 commit → 改 state(带异步逻辑的 "状态修改前置任务");- 一句话:同步改状态用 commit,异步逻辑后改状态用 dispatch。