Vuex 辅助函数的使用

mapState、mapGetters、mapMutations、mapActions 的使用方法和映射规则

问题

如何使用 Vuex 中的 mapState、mapGetters、mapMutations、mapActions 等辅助函数来简化状态管理?

解答

基本概念

辅助函数将 Vuex store 中的属性映射到 Vue 组件实例上,方便直接访问和操作。映射关系如下:

  • mapState/mapGetters → computed
  • mapMutations/mapActions → methods

引入方式

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'

mapState

将 state 映射到 computed 属性:

computed: {
  ...mapState({
    input: state => state.inputVal,
    n: state => state.n
  })
}

使用对象形式的优点:可以重命名属性,避免命名冲突;可以在函数内部访问完整的 state。

mapGetters

将 getters 映射到 computed 属性:

computed: {
  ...mapGetters({
    NumN: 'NumN'
  })
}

getters 类似组件的 computed,会监听 state 变化并自动更新。

mapActions

将 actions 映射到 methods:

methods: {
  ...mapActions({
    add: 'handleTodoAdd',
    change: 'handleInput'
  })
}

等价于手动调用:

methods: {
  handleInput(e) {
    let val = e.target.value
    this.$store.dispatch('handleInput', val)
  },
  handleAdd() {
    this.$store.dispatch('handleTodoAdd')
  }
}

mapMutations

将 mutations 映射到 methods:

methods: {
  ...mapMutations({
    handleAdd: 'handleMutationsAdd'
  })
}

适用于简单的数据修改,不涉及异步操作和复杂业务逻辑。

模块化与命名空间

开启命名空间:

export default {
  namespaced: true,
  state: { ... },
  getters: { ... },
  mutations: { ... },
  actions: { ... }
}

使用带命名空间的辅助函数:

computed: {
  ...mapState('todo', {
    inputVal: state => state.inputVal
  })
},
methods: {
  ...mapActions('todo', ['handleTodoAdd'])
}

访问模块化后的 state:

this.$store.state.todo.inputVal

关键点

  • mapState 和 mapGetters 映射到 computed,mapMutations 和 mapActions 映射到 methods
  • 使用对象形式可以重命名属性,使用数组形式保持原名
  • mutations 用于同步修改 state,actions 用于处理异步操作和业务逻辑
  • 开启 namespaced: true 避免模块间的命名冲突
  • 使用扩展运算符 ... 可以与组件自身的 computed 和 methods 合并