Vuex Basic tutorial series 🎉

Getters

Vuex’s getters option can be thought of as a computed property of the Store, which can derive entirely new states based on one or more states. Getters also have caching properties and are recalculated only when their dependent values change.

Getters are most effective when multiple components share the same derived state, without having each component individually define computed properties to filter or combine derived state, or using shared functions to filter or combine derived state by importing modules.

First, let’s combine a new state through the getter.

export default {
    state: {
        firstName: 'Eich'.lastName: 'Brendan'
    },
    getters: {
        fullName: (state) = > state.lastName + state.firstName
    }
}
Copy the code

Next, the state is filtered using the getter, and we also have access to the getters option with the second argument.

const store = new Vuex.Store({
    state: {
        firstName: 'Brendan '.lastName: 'Eich'.names: ['James Gosling'.'Tim Berners-Lee'],},getters: {
        fullName: state= > state.firstName + state.lastName,
        namesStartWithT: (state, **getters**) = > {
            const combines = state.names.concat([getters.fullName]);
            return combines.filter(item= > item.toLowerCase().startsWith('t')); }}});Copy the code

A getter can also return a function, which is useful for more flexible filtering of state in the Store.

const store = new Vuex.Store({
    state: {
        firstName: 'Brendan '.lastName: 'Eich'.names: ['James Gosling'.'Tim Berners-Lee'],},getters: {
        fullName: state= > state.firstName + state.lastName,
        findNames: (state, getters) = > **(name)** **=>** **{**
            const combines = state.names.concat([getters.fullName]);
            return combines.filter(item= >item.indexOf(name) ! = = -1); * * * *}}});//Use
store.getters.findNames('a');
Copy the code

Note that if the getter returns a function, the result of the calculation is not cached.

Access the Getter in the Vue component

  1. The importstoreInstance or injected through the root component$storeTo access thegettersOptions.
  2. usemapGettersTool method.

MapGetters tool method

The mapGetters method makes it easy to mapGetters to computed properties of a component.

Using arrays, you can quickly map computed properties with the same name as getters

{
	computed: Vuex.mapGetters(['fullName'.'names'])}Copy the code

If you want to customize the name of the calculated property, you can use the object value format.

{
	computed: Vuex.mapGetters({ name: 'fullName'})}Copy the code

Finally, don’t forget that you can use the ES6 expansion operator to merge computed properties of a map with other computed properties.

Actions

Actions is the repackaging of mutations, because the latter is not only relied on by the project code but also by Vuex’s own state change record, so it can only carry out pure synchronous state change operation. Actions is dedicated to service business code and supports both synchronous and asynchronous state change operations.

An action cannot change the state directly, but must change the state indirectly by submitting mutation in it.

Here is a schematic diagram of the flow of an asynchronous state change:

In the figure above, the Backend API sends interface requests in the action to obtain back-end data, while Devtools synchronously obtains status data and change records from mutation during Vuex debugging.

Here is a basic example of implementing the above image:

<div id="app">
    <p>{{age}} / {{name}}</p>
    <button @click="updateInfo">UpdateInfo</button>
</div>
Copy the code
const store = new Vuex.Store({
    state: {
        age: 1.name: 'Sam'
    },
    mutations: {
        updateAge(state) {
            state.age = 18;
        },
        updateName(state) {
            state.name = 'Bob'; }},actions: {
        asyncUpdateAge(context) {
            context.commit('updateAge');
        },
        asyncUpdateName({ commit }) {
            commit('updateName'); }}});new Vue({
    el: '#app',
    store,
    computed: Vuex.mapState(['age'.'name']),
    methods: {
        updateInfo() {
            this.$store.dispatch('asyncUpdateAge');
            this.$store.dispatch('asyncUpdateName'); }}})Copy the code

The use form of actions is exactly the same as mutations, with slight differences reflected in:

  1. actionusedispatchMethod to distribute,muationIs the usecommitMethod to commit.
  2. actionThe event handler receives an andstoreHaving the same properties and methodscontextObject,But they are not really the same object), so you can passcontext.commitTo submitmutation; throughcontext.gettersIn order to getgetter; throughcontext.stateIn order to getstate; throughcontext.dispatchTo distribute the restaction. The retrieval of parameters can also be simplified with the help of ES6’s deconstruction operators({ commit, dispatch, state, getters })

Payload

The action is triggered by the dispatch method, which has the same form of payload as the COMMIT method of muation.

const store = new Vuex.Store({
      state: {
          age: 0.name: 'Sam'
      },
      mutations: {
          updateAge(state, payload) {
              state.age = payload;
          },
          updateName(state, payload){ state.name = payload.name; }},actions: {
          asyncUpdateAge(context, payload) {
              context.commit('updateAge', payload);
          },
          asyncUpdateName({ commit }, payload) {
              commit('updateName', payload); }}});Copy the code

The Dispatch method distributes the action and delivers the payload.

this.$store.dispatch('asyncUpdateAge'.20);
this.$store.dispatch('asyncUpdateName', { name: 'Bob' });
//or
this.$store.dispatch({
	type:'asyncUpdateName'.name:'Bob'
})
Copy the code

Actions + Promise

Returning a Promise object in the action allows us to listen for completion of an asynchronous state change.

const store = new Vuex.Store({
    state: {
        age: 0.name: 'Sam'
    },
    mutations: {
        updateAge(state, payload) {
            state.age = payload.age;
        },
        updateName(state, payload){ state.name = payload.name; }},actions: {
        asyncUpdateAge(context, payload) {
            return new Promise(resolve= > {
                setTimeout(() = > {
                    context.commit('updateAge', payload);
                    resolve();
                }, 1000); })},asyncUpdateName({ commit, dispatch }, payload) {
            return new Promise(resolve= > {
                setTimeout(() = > {
                    commit('updateName', payload);
                    resolve()
                }, 1500);
            });
        },
        asyncUpdateInfo({ dispatch }, payload) {
            const updateAge = dispatch('asyncUpdateAge', payload);
            const updateName = dispatch('asyncUpdateName', payload);
            return Promise.all([updateAge, updateName])
        }
    }
});
Copy the code

The corresponding callback is performed using the Promise state returned in the Dispatch method.

this.$store.dispatch({
    type: 'asyncUpdateInfo'.name: 'Bob'.age: 18
}).then(() = > {
    alert('success!!! ')})Copy the code

Finally, to avoid callback hell we can use the latest async and await syntax instead of.then callbacks.

async updateInfo() {
      await this.$store.dispatch({...})
}
Copy the code

Distribute the Action in the Vue component

  1. By importing thestore.dispatchOr injected using the root component$storeTo distributeaction
  2. usemapActionsTool methods willactionMethods that map to component instances.

MapActions tool method

Using the mapActions tool we can easily map Store actions to component methods. For easier calls.

Using the array format, you can quickly map Actions to methods with the same name as component instances.

{
	methods: Vuex.mapActions(['asyncUpdateInfo'])}Copy the code

If you need to rename a method, you can use the object format

{
	methods: Vuex.mapActions({
		updateInfo : 'asyncUpdateInfo'})}Copy the code