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