Alex-Programer

Alex-Programer

随缘博客,不定期更新不确定的内容~
github
twitter

Basic Usage of Vuex

Official Definition#

Vuex is a state management pattern designed for Vue.js applications. It adopts a centralized storage to manage the state of all components in the application and ensures that the state changes in a predictable manner according to corresponding rules.

Injecting Vuex#

import store from "./store";

new Vue({
  store,
});

store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    msg: "hello world",
  },
  mutations: {},
  actions: {},
});

Accessing State#

In any component, you can access the msg like this:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <h2>{{$store.state.msg}}</h2>
  </div>
</template>

Modifying State#

Let mutations provide a method to modify the state:

mutations: {
  setMsg(state, newMsg) {
    state.msg = newMsg
  }
}

Then let actions submit the modification request:

actions: {
  setMsg ({ commit }) {
    commit('setMsg', 'hello')
  }
}

Trigger the modification action in other components:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <h2>{{$store.state.msg}}</h2>
  </div>
</template>

<script>
export default {
  mounted () {
    this.$store.dispatch('setMsg')
  }
}
</script>

Considerations#

The above example is a simple state management. state stores the state, mutations provides methods to modify the state, and actions is responsible for triggering the methods to modify the state and submitting the modified data. In the example, the data modified in actions is done manually, but in actual work, it should be the data submitted by the request. However, there is an obvious problem in the example, anyone can modify (dispatch) the state.

Namespaces#

If the project is complex enough, you can use the namespace provided by Vuex to modify the state. To use namespaces, you need to use modules in addition to vuex. modules is an object, and its structure also consists of state, mutations, and actions. The difference is that it has an additional namespaced property to use namespaces.

Three Methods to Modify State#

Dispatch#

First, extract the original content into a modules:

store.js

import Vue from "vue";
import Vuex from "vuex";
import home from "./modules/home";

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    home,
  },
});

./modules/home.js

export default {
  namespaced: true,
  state: {
    msg: "hello world",
  },
  actions: {
    setMsg({ commit }) {
      commit("setMsg", "hello");
    },
  },
  mutations: {
    setMsg(state, newMsg) {
      state.msg = newMsg;
    },
  },
};

Finally, retrieve and modify the state:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <h2>{{$store.state.home.msg}}</h2>
  </div>
</template>

<script>
export default {
  mounted () {
    this.$store.dispatch('home/setMsg')
  }
}
</script>

Observe the difference between the final modification and the previous one. The only difference is that there is an additional home when retrieving and modifying the state, which increases the usage threshold. However, at least it can identify which module's state is being operated on.

There is another equivalent way to modify the state through modules:

mapActions#

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <h2>{{$store.state.home.msg}}</h2>
  </div>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions('home', ['setMsg'])
  },
  mounted () {
    this.setMsg()
  }
}
</script>

After executing mapActions, it returns an object. After spreading it, a setMsg method will be added to the current instance. Calling this method will trigger the modification of the state.

createNamespacedHelpers#

Both of the above methods have an obvious problem. If there are many states that need to be modified in the current component, it means that there will be many layers of home. By using createNamespacedHelpers provided by Vuex, this problem can be solved in a friendly way.

<template>
  <div class='about'>
    <h1>This is an about page</h1>
    <h2>{{$store.state.home.msg}}</h2>
  </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
const { mapActions } = createNamespacedHelpers('home')

export default {
  methods: {
    ...mapActions(['setMsg'])
  },
  mounted () {
    this.setMsg()
  }
}
</script>

Simplify Value Retrieval#

The previous examples did not mention the issue of value retrieval, and it is not recommended to do so in actual work. Vuex provides a mapState method to simplify value retrieval.

<template>
  <div class='about'>
    <h1>This is an about page</h1>
    <h2>{{msg}}</h2>
  </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
const { mapActions, mapState } = createNamespacedHelpers('home')

export default {
  computed: {
    ...mapState(['msg'])
  },
  methods: {
    ...mapActions(['setMsg'])
  },
  mounted () {
    this.setMsg()
  }
}
</script>

Extract Variables#

Recall how many times the word setMsg appeared. It appeared in the component, in the store or modules. At this time, it is advocated to extract this setMsg into a constant to be saved. This makes it easier for oneself or others to maintain.

./store/action-type.js

export const SET_MSG = "setMsg";

When using it, try to avoid using setMsg directly. This makes it easier for yourself or others to maintain.

Summary#

The convenience of Vuex is self-evident. According to the complexity of the project, it provides a progressive enhancement solution. When the project is simple, basic requirements can be met without using modules. If the complexity increases, modules is the best choice. If there are not many modules, you can simply use dispatch. Even if there are many modules, createNamespacedHelpers has paved the way for subsequent work.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.