preface

When a component gets more than one state, declaring computed properties becomes repetitive and redundant. We can use the helper function mapState to generate computed properties faster and more succinctly.

So let’s be clear, what mapState is doing is helping us translate the values of an object or an array into a notation for calculating properties. Similarly, other auxiliary functions are similar, as long as you know the implementation of mapState, everything else is basically understood.

Note: this reading is vuex 2.0.0 version, please stamp here.

To prepare

Before reading, we need to be familiar with the use of some methods:

  • Array.isArray()
  • Array.prototype.map()
  • Object.keys()

Interpretation of the

How to use mapState:

import { mapState } from 'vuex'

export default {
  computed: mapState([
    // Map this.count to store.state.count
    'count'])}Copy the code

MapState returns an object, and we know that the above code will end up like this:

import { mapState } from 'vuex'

export default {
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}
Copy the code

So let’s start by looking at what mapState does.

Again from vuex’s APi, open the SRC /index.js file and you can see the mapState exposed by Vuex in the code at the bottom:

export default {
  Store,
  install,
  mapState,
  mapMutations,
  mapGetters,
  mapActions
}
Copy the code

After positioning you can find the first introduction:

import { mapState, mapMutations, mapGetters, mapActions } from './helpers'
Copy the code

Open the SRC /helpers.js file and you’ll find an implementation of mapState.

normalizeMap

NormalizeMap normalizeMap normalizeMap normalizeMap Locate the normalizeMap method:

function normalizeMap (map) {
  return Array.isArray(map)
    ? map.map(key= > ({ key, val: key }))
    : Object.keys(map).map(key= > ({ key, val: map[key] }))
}
Copy the code

This method basically formats the States argument passed in by mapState. We know that the States argument will be passed in two forms, one as an array and the other as an object method.

For example:

// Pass it in as an array
mapState([
  'count'.'add'
])

// passed in as an object method
mapState({
  count: state= > state.count,
  countAlias: 'count'
})
Copy the code

The normalizeMap method will look like this:

// Pass it in as an array[{key: 'count'.val: 'count'
  },
  {
    key: 'add'.val: 'add'}]// passed in as an object method[{key: count,
    val: state= > state.count
  },
  {
    key: countAlias,
    val: 'count'}]Copy the code

mapState

Now that we know the normalizeMap method implementation, let’s go back to the mapState method implementation:

export function mapState (states) {
  const res = {}
  normalizeMap(states).forEach(({ key, val }) = > {
    res[key] = function mappedState () {
      return typeof val === 'function'
        ? val.call(this.this.$store.state, this.$store.getters)
        : this.$store.state[val]
    }
  })
  return res
}
Copy the code

Iterate over the array just returned after normalizeMap formatting to concatenate a computed object (with a return value).

There are two judgments for val in the object of normalizeMap’s return array. If it is not a function, look directly for this.$store.state[val] to return state. If it is a function, call is used to point this of the function val to the vue instance, then state and getters are passed in, and val is executed.

Val function

If val were a function, it might be a little hard to understand. For example, the argument passed might look something like this:

computed: mapState({
  countPlusLocalState (state) {
    return state.count + this.localCount
  }
})
Copy the code

NormalizeMap returns the following objects:

[{key: 'countPlusLocalState'.val: function (state) {
      return state.count + this.localCount
    }
  }
]
Copy the code

And then we go through mapState and the res that we get back is. The function val is executed once, returning the value of the function.

{
  countPlusLocalState: function mappedState () {
    return this.$store.state.count + this.localCount
  }
}
Copy the code

At this point, the interpretation of mapState is complete. In addition, mapState often uses an es6 extension operator, which is not an implementation of VUex, but a new feature of ES6:

computed: {
  localComputed () { / *... * / },
  
  // Use the object expansion operator to blend this object into an external object. mapState({// ...})}Copy the code

The exception is to note that if you want to use es6’s extension operators, you also need to introduce a Babel package: babel-plugin-transform-object-rest-spread.

conclusion

MapState doesn’t have much code, and its main function is to convert arrays or objects passed in to code that can be recognized by computed attributes. One thing that’s hard to understand is that the object with the return value of the function is a little bit convoluted, so watch it a few times to understand.

MapState inside the code is very simple and exquisite, mainly using some built-in JS functions to do processing, if I am, estimate will always write for loop implementation, haha, from which to gain a lot of knowledge. This concludes the interpretation of the Vuex.