返回

Vuex 辅助函数探秘:作用、用法与源码剖析

前端

Vuex 辅助函数简介

Vuex 辅助函数是一组内置的函数,可帮助开发者轻松地将 Vuex 状态、操作和计算属性映射到组件中。这些辅助函数包括:

  • mapState:将 Vuex 状态映射到组件的计算属性中。
  • mapActions:将 Vuex 操作映射到组件的方法中。
  • mapGetters:将 Vuex 计算属性映射到组件的计算属性中。
  • mapMutations:将 Vuex 变更映射到组件的方法中。

这些辅助函数的使用非常简单,只需要在组件中引入并调用即可。例如:

import { mapState } from 'vuex'

export default {
  computed: {
    ...mapState([
      'count'
    ])
  }
}

通过以上代码,我们就可以将 Vuex 的 count 状态映射到组件的计算属性中,然后在组件中直接使用 this.count 即可。

Vuex 辅助函数源码分析

为了更好地理解 Vuex 辅助函数的用法和原理,我们接下来深入源码,剖析这些辅助函数的实现细节。

mapState 源码分析

mapState 函数的源码位于 vuex/dist/vuex.common.js 文件中,其代码如下:

export function mapState (mapper) {
  return normalizeNamespace(arguments.length, mapper) ?
    mapStateToProps(arguments[1]) :
    mapStateToProps(mapper)
}

function mapStateToProps (map) {
  return (state) => {
    const res = {}
    normalizeMap(map).forEach(({ key, val }) => {
      res[key] = val(state)
    })
    return res
  }
}

从源码中可以看到,mapState 函数首先对传入的第一个参数进行处理,如果该参数是一个对象,则将其作为状态映射器,否则将其作为命名空间。

如果传入的是一个对象,则调用 mapStateToProps 函数,该函数返回一个计算属性函数,该函数接收 Vuex 状态作为参数,并返回一个对象,其中包含了映射到组件计算属性中的 Vuex 状态。

如果传入的是一个命名空间,则首先调用 normalizeNamespace 函数,该函数返回一个对象,其中包含了命名空间和状态映射器。然后调用 mapStateToProps 函数,并传入状态映射器作为参数,最后返回一个计算属性函数。

mapActions 源码分析

mapActions 函数的源码位于 vuex/dist/vuex.common.js 文件中,其代码如下:

export function mapActions (mapper) {
  return normalizeNamespace(arguments.length, mapper) ?
    mapActionsNamespace(arguments[1]) :
    mapActionsNamespace(mapper)
}

function mapActionsNamespace (map) {
  return (dispatch) => {
    const res = {}
    normalizeMap(map).forEach(({ key, val }) => {
      res[key] = function (...args) {
        return dispatch(val.bind(null, ...args))
      }
    })
    return res
  }
}

从源码中可以看到,mapActions 函数首先对传入的第一个参数进行处理,如果该参数是一个对象,则将其作为操作映射器,否则将其作为命名空间。

如果传入的是一个对象,则调用 mapActionsNamespace 函数,该函数返回一个操作映射函数,该函数接收 Vuex 的 dispatch 函数作为参数,并返回一个对象,其中包含了映射到组件方法中的 Vuex 操作。

如果传入的是一个命名空间,则首先调用 normalizeNamespace 函数,该函数返回一个对象,其中包含了命名空间和操作映射器。然后调用 mapActionsNamespace 函数,并传入操作映射器作为参数,最后返回一个操作映射函数。

mapGetters 源码分析

mapGetters 函数的源码位于 vuex/dist/vuex.common.js 文件中,其代码如下:

export function mapGetters (mapper) {
  return normalizeNamespace(arguments.length, mapper) ?
    mapGettersNamespace(arguments[1]) :
    mapGettersNamespace(mapper)
}

function mapGettersNamespace (map) {
  return (getters) => {
    const res = {}
    normalizeMap(map).forEach(({ key, val }) => {
      // the getter is already a function
      // so just expose it directly
      res[key] = val
    })
    return res
  }
}

从源码中可以看到,mapGetters 函数首先对传入的第一个参数进行处理,如果该参数是一个对象,则将其作为计算属性映射器,否则将其作为命名空间。

如果传入的是一个对象,则调用 mapGettersNamespace 函数,该函数返回一个计算属性映射函数,该函数接收 Vuex 的 getters 对象作为参数,并返回一个对象,其中包含了映射到组件计算属性中的 Vuex 计算属性。

如果传入的是一个命名空间,则首先调用 normalizeNamespace 函数,该函数返回一个对象,其中包含了命名空间和计算属性映射器。然后调用 mapGettersNamespace 函数,并传入计算属性映射器作为参数,最后返回一个计算属性映射函数。

mapMutations 源码分析

mapMutations 函数的源码位于 vuex/dist/vuex.common.js 文件中,其代码如下:

export function mapMutations (mapper) {
  return normalizeNamespace(arguments.length, mapper) ?
    mapMutationsNamespace(arguments[1]) :
    mapMutationsNamespace(mapper)
}

function mapMutationsNamespace (map) {
  return (commit) => {
    const res = {}
    normalizeMap(map).forEach(({ key, val }) => {
      res[key] = function (...args) {
        return commit(val.bind(null, ...args))
      }
    })
    return res
  }
}

从源码中可以看到,mapMutations 函数首先对传入的第一个参数进行处理,如果该参数是一个对象,则将其作为变更映射器,否则将其作为命名空间。

如果传入的是一个对象,则调用 mapMutationsNamespace 函数,该函数返回一个变更映射函数,该函数接收 Vuex 的 commit 函数作为参数,并返回一个对象,其中包含了映射到组件方法中的 Vuex 变更。

如果传入的是一个命名空间,则首先调用 normalizeNamespace 函数,该函数返回一个对象,其中包含了命名空间和变更映射器。然后调用 mapMutationsNamespace 函数,并传入变更映射器作为参数,最后返回一个变更映射函数。

结语

通过本文的学习,相信您已经对 Vuex 辅助函数有了更深入的了解。这些辅助函数可以帮助我们轻松地将 Vuex 状态、操作、计算属性和变更映射到组件中,从而简化开发流程,提高开发效率。

希望本文对您有所帮助,也欢迎您在评论区留下您的想法和建议。