Vuex核心概念 #
概述 #
Vuex 包含五个核心概念,它们共同构成了一个完整的状态管理系统:
text
┌──────────────────────────────────────────────────────┐
│ Vuex 五大核心概念 │
├──────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌───────────┐ │
│ │ State │ │ Getter │ │ Mutation │ │
│ │ 状态 │ │ 派生 │ │ 变更 │ │
│ └─────────┘ └─────────┘ └───────────┘ │
│ │ │ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ Module 模块 │ │
│ │ 组织和管理以上四个概念 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ Action 动作 │ │
│ │ 处理异步操作,提交变更 │ │
│ └─────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────┘
State - 状态 #
什么是 State? #
State 是 Vuex 中的状态存储对象,是应用中唯一的数据源。
javascript
const store = createStore({
state: {
// 用户信息
user: {
name: 'John',
age: 25
},
// 购物车
cart: [],
// 应用设置
settings: {
theme: 'dark',
language: 'zh-CN'
}
}
})
访问 State #
直接访问 #
javascript
// 在组件中
this.$store.state.count
// 使用计算属性
computed: {
count() {
return this.$store.state.count
}
}
mapState 辅助函数 #
javascript
import { mapState } from 'vuex'
export default {
computed: {
// 对象展开运算符
...mapState({
// 箭头函数
count: state => state.count,
// 传字符串参数
countAlias: 'count',
// 使用 this
countPlusLocalState(state) {
return state.count + this.localCount
}
})
}
}
State 设计原则 #
javascript
// 推荐:扁平化结构
state: {
users: {
byId: {
1: { id: 1, name: 'John' },
2: { id: 2, name: 'Jane' }
},
allIds: [1, 2]
}
}
// 不推荐:深层嵌套
state: {
data: {
users: {
list: {
items: {
// ...
}
}
}
}
}
Getter - 派生状态 #
什么是 Getter? #
Getter 类似于计算属性,用于从 store 中的 state 派生出一些状态。
javascript
const store = createStore({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
// 获取完成的 todos
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
// 获取完成的 todos 数量
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
访问 Getter #
javascript
// 直接访问
this.$store.getters.doneTodos
// 使用 mapGetters
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters([
'doneTodos',
'doneTodosCount'
])
}
}
Getter 传参 #
javascript
getters: {
// 返回一个函数
getTodoById: state => id => {
return state.todos.find(todo => todo.id === id)
}
}
// 使用
this.$store.getters.getTodoById(1)
Mutation - 变更 #
什么是 Mutation? #
Mutation 是更改 Vuex 的 store 中的状态的唯一方法。
javascript
const store = createStore({
state: {
count: 0
},
mutations: {
// 同步修改状态
INCREMENT(state) {
state.count++
},
// 带参数的 mutation
SET_COUNT(state, payload) {
state.count = payload
},
// 对象风格的 payload
UPDATE_USER(state, { name, age }) {
state.user.name = name
state.user.age = age
}
}
})
提交 Mutation #
javascript
// 普通提交
this.$store.commit('INCREMENT')
// 带 payload 提交
this.$store.commit('SET_COUNT', 10)
// 对象风格提交
this.$store.commit({
type: 'SET_COUNT',
value: 10
})
Mutation 规则 #
text
Mutation 规则
├── 必须是同步函数 ──── 便于追踪状态变化
├── 使用常量命名 ────── 提高可维护性
├── 第一个参数是 state ─ 接收当前状态
└── 不要直接调用 ────── 必须通过 commit
mapMutations 辅助函数 #
javascript
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations([
'INCREMENT',
'SET_COUNT'
]),
// 重命名
...mapMutations({
add: 'INCREMENT'
})
}
}
Action - 动作 #
什么是 Action? #
Action 类似于 Mutation,不同在于:
- Action 提交的是 Mutation,而不是直接变更状态
- Action 可以包含任意异步操作
javascript
const store = createStore({
state: {
count: 0
},
mutations: {
SET_COUNT(state, value) {
state.count = value
}
},
actions: {
// 异步操作
async fetchCount({ commit }) {
const response = await fetch('/api/count')
const data = await response.json()
commit('SET_COUNT', data.count)
},
// 带参数
async updateCount({ commit }, value) {
await fetch('/api/count', {
method: 'POST',
body: JSON.stringify({ count: value })
})
commit('SET_COUNT', value)
}
}
})
分发 Action #
javascript
// 普通分发
this.$store.dispatch('fetchCount')
// 带 payload 分发
this.$store.dispatch('updateCount', 10)
// 对象风格分发
this.$store.dispatch({
type: 'updateCount',
value: 10
})
组合 Action #
javascript
actions: {
// 顺序执行
async actionA({ commit }) {
commit('SET_DATA', await getData())
},
// 等待其他 action 完成
async actionB({ dispatch, commit }) {
await dispatch('actionA')
commit('SET_OTHER_DATA', await getOtherData())
},
// 并行执行
async fetchAll({ dispatch }) {
await Promise.all([
dispatch('fetchUsers'),
dispatch('fetchProducts')
])
}
}
mapActions 辅助函数 #
javascript
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions([
'fetchCount',
'updateCount'
]),
// 重命名
...mapActions({
load: 'fetchCount'
})
}
}
Module - 模块 #
什么是 Module? #
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。Module 可以将 store 分割成模块。
javascript
// 模块定义
const userModule = {
namespaced: true,
state: {
name: '',
age: 0
},
mutations: {
SET_NAME(state, name) {
state.name = name
}
},
actions: {
async fetchUser({ commit }) {
const user = await fetchUser()
commit('SET_NAME', user.name)
}
},
getters: {
userName: state => state.name
}
}
// 组合模块
const store = createStore({
modules: {
user: userModule,
cart: cartModule
}
})
模块访问 #
javascript
// 访问模块状态
this.$store.state.user.name
// 访问模块 getter
this.$store.getters['user/userName']
// 提交模块 mutation
this.$store.commit('user/SET_NAME', 'John')
// 分发模块 action
this.$store.dispatch('user/fetchUser')
数据流图 #
text
┌──────────────────────────────────────────────────────────────┐
│ Vuex 数据流 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ │ │
│ │ Component │ │
│ │ (组件) │ │
│ │ │ │
│ └──────┬──────┘ │
│ │ │
│ │ dispatch('action') │
│ ▼ │
│ ┌─────────────┐ │
│ │ │ │
│ │ Actions │ ──────── 异步操作 ────────┐ │
│ │ (动作) │ │ │
│ │ │ │ │
│ └──────┬──────┘ │ │
│ │ │ │
│ │ commit('mutation') │ │
│ ▼ │ │
│ ┌─────────────┐ │ │
│ │ │ │ │
│ │ Mutations │ ◀────────────────────────┘ │
│ │ (变更) │ │
│ │ │ │
│ └──────┬──────┘ │
│ │ │
│ │ mutate state │
│ ▼ │
│ ┌─────────────┐ │
│ │ │ │
│ │ State │ ────────▶ Getters ────────┐ │
│ │ (状态) │ │ │
│ │ │ │ │
│ └─────────────┘ │ │
│ │ │ │
│ │ │ │
│ └──────────────────────────────────┘ │
│ │ │
│ │ render │
│ ▼ │
│ ┌─────────────┐ │
│ │ Component │ │
│ └─────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
总结 #
| 概念 | 作用 | 特点 |
|---|---|---|
| State | 存储状态 | 响应式、单一数据源 |
| Getter | 派生状态 | 缓存、可传参 |
| Mutation | 同步修改 | 唯一修改途径 |
| Action | 异步操作 | 提交 Mutation |
| Module | 模块化 | 命名空间隔离 |
继续学习 第一个Store,创建你的第一个 Vuex Store。
最后更新:2026-03-28