What is a Vuex

Vuex is a state management pattern developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application, and rules to ensure that the state changes in a predictable manner. Vuex is also integrated into Vue’s official debugging tools, providing advanced debugging features such as zero-configuration time-travel debugging, and state snapshot import and export.

Here is a simple schematic of the idea of “one-way data flow”

Note: When our application encountersMultiple components share state, the conciseness of a one-way data flow can be easily broken

Vue has five core concepts: state, getters, mutations, Actions, and Modules.

  1. State => Basic data
  2. Getters => Data derived from the base data
  3. Mutations => The method of submitting the change data, synchronization!
  4. Actions => Like a decorator, packaged mutations, enabling it to be asynchronous.
  5. Modules => Modular Vuex

Under what circumstances should I use Vuex? Vuex helps manage shared state and comes with more concepts and frameworks. This requires a balance between short – and long-term benefits. If you don’t plan to develop large, single-page applications, using Vuex can be tedious and redundant. That’s true — if your application is simple enough, you’re better off not using Vuex. A simple store mode (opens new Window) should suffice. However, if you need to build a medium to large single-page application, you are likely to be thinking about how to better manage state outside of components, and Vuex would be a natural choice. Officials recommend that Vuex be considered in the case of medium to large projects. Personally, I use VUEX only when non-parent components of a page need to update data synchronously in real time, and rarely otherwise.

How is Vuex used

See figure:The whole dotted line is the Vuex, which we can think of as a public warehouse store. In Store, there are Actions, Mutations, and State. The whole logic is that the component calls the method in Actions through Dispatch, Actions calls the method in Mutations through Commit, and Mutatisons change the value in State.

Vuex is required to download the introduction, I will not do much to introduce.

The use of Vuex

In vuex, there is only one method for storing values, and there are two synchronous methods for storing values and one asynchronous method. First, index.js in the store folder defaults to this:

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

Vue.use(Vuex);

export default new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  modules: {},});Copy the code

The first is synchronous transmission

  1. First define a type (any type) in the state property
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    // Define a numeric type
    number: 6,},mutations: {},
  actions: {},
  modules: {},});Copy the code
  1. The value is in the computed attribute on the corresponding page —— Saves the value in methods
<template>
  <div class="home">// Display the page<button @click="btn">{{ number }}</button>
  </div>
</template>

<script>
// Introduce the vuex attribute mapState
import { mapState } from "vuex";
export default {
  data() {
    return {};
  },
  computed: {
    // Use this method. mapState({// The arrow function is recommended for brief introduction
      number: (state) = > state.number,
    }),
  },
  methods: {
    btn() {
      // Synchronizes the value of the first
      // Use commit (' attribute name ', 'attribute value')
      this.$store.commit("newNumber".Awesome!); ,}}};</script>
Copy the code
  1. Store the value and assign it to the defined number in the store
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    number: 6,},mutations: {
    // Take two arguments (state, val) to the attribute name passed.
    // Val is the value of the attribute passed in
    newNumber(state, val){ state.number = val; }},actions: {},
  modules: {},});Copy the code

The second is synchronous transmission

  1. Again, define a type (any type) in the state property
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    // Define a numeric type
    number: 6,},mutations: {},
  actions: {},
  modules: {},});Copy the code
  1. The value is in the computed attribute on the corresponding page —— Saves the value in methods
<template>
  <div class="home">// Display the page<button @click="btn">{{ number }}</button>
  </div>
</template>

<script>
// Introduce the vuex attribute mapState
import { mapState } from "vuex";
export default {
  data() {
    return {};
  },
  computed: {
    // Use this method. mapState({// The arrow function is recommended for brief introduction
      number: (state) = > state.number,
    }),
  },
  methods: {
    btn() {
      // Synchronize the value of the second
      // Use dispatch (' property name ', 'property value')
      this.$store.dispatch("setNumber".Awesome!)}}};</script>
Copy the code
  1. Store the value and assign it to the defined number in the store

The Action function takes a context object that has the same methods and properties as the Store instance, so you can call context.com MIT and submit a mutation, Or get state and getters from context.state and context.getters. When we look at [Modules] later, you’ll see why the Context object is not the Store instance itself. The vuEX website has a detailed introduction

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

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    number: 6,},mutations: {
    // This step is also required
    newNumber(state, val){ state.number = val; }},actions: {
    // The first parameter is wrapped in {} and the second is the value of the property
    setNumber({commit}, val) {
      commit("newNumber", val)
    }
  },
  modules: {},});Copy the code

The third is asynchronous value passing

  1. Again, define a type (any type) in the state property
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    // Define a numeric type
    number: 6,},mutations: {},
  actions: {},
  modules: {},});Copy the code
  1. Value In the computed attribute on the corresponding page —— Use mapActions in the method to save the value
<template>
  <div class="home">// Page display // asynchronous pass value must be followed by the event parameter<button @click="btn(666)">{{ number }}</button>
  </div>
</template>

<script>
// Introduce the vuex attributes mapState,mapActions
import{mapState, mapActions}from "vuex";
export default {
  data() {
    return {};
  },
  computed: {
    // Use this method. mapState({// The arrow function is recommended for brief introduction
      number: (state) = > state.number,
    }),
  },
  methods: {
    ...mapActions({
      // Event name: "attribute name"
      btn: "setNumber",})}};</script>
Copy the code
  1. Store the value and assign it to the defined number in the store
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    number: 6,},mutations: {
    // This step is also required
    newNumber(state, val){ state.number = val; }},actions: {
    // The first parameter is wrapped in {} and the second is the value of the property
    setNumber({commit}, val) {
      commit("newNumber", val)
    }
  },
  modules: {},});Copy the code

That is the use of VUEX, the first synchronization method is relatively simple. The second type of synchronization is similar to the third type of asynchrony in that it is the same in the store, except when storing values in the page.

Vuex is modular in use

Why to use modularity is to divide VUEX into different modules, which are easy to maintain both in terms of project and structure. In vuEX, we write state, getters, mutations and actions in one file. Imagine if our project is very big, such as taobao, so big, so we want to maintain vuex content will be much more special, such as the “shopping cart” need vuex, “Settings” to use vuex, “home page” also requires vuex, so if we write a file, will appear code is “fat”. This store file ends up with tens of thousands of lines of code. How to maintain?

There are many ways to write modularity, but I’ll show you what I think is simple.

  1. First create a folder in the store (user) with a default index.js file \

State, mutations and actions are pulled out and thrown by default in index.js under user, and namespace: true is required

export default {
  state: {},
  mutations: {},
  actions: {},
  namespaced: true};Copy the code
  1. Then introduce the created module in the store’s index.js
import Vue from "vue";
import Vuex from "vuex";
// Import index.js under user
import user from "./user";

Vue.use(Vuex);

export default new Vuex.Store({
  // Call here
  modules: { user },
});

Copy the code
  1. In the page to introduce the value store value of two method names, save the value of the same three values only one \

Note that the first attribute name in parentheses needs to use the introduced user/***, which is hierarchical.

<template>
  <div class="home">// The method followed by the argument is the third value asynchronous<button @click="btn(123)">{{ number }}</button>
  </div>
</template>

<script>
// Introduce two methods of vuex
import { mapState, mapActions } from "vuex";
export default {
  data() {
    return {};
  },
  // In the computed properties
  computed: {
    ...mapState({
      // There is only one value
      user: (state) = > state.user.num,
    }),
  },
  // Store the value in the method
  methods: {
    btn() {
      // Save the value of the first synchronization
      // this.$store.commit("user/setUser", 5);
      // Save the value of the second synchronization
      // this.$store.dispatch("user/setUserActions",1)
    },
    // The third type of asynchrony. mapActions({btn: "user/setUserActions",})}};</script>
Copy the code
  1. In index.js under user, same as before
export default {
  state: {
    number: 5,},mutations: {
    setUser(state, val){ state.number = val; }},actions: {
    setUserActions({ commit }, val) {
      commit("setUser", val); }},namespaced: true};Copy the code

The modular use of VUEX is not very different from the normal use. The emphasis is on the need for hierarchical attribute names when storing values. The main reason is that multiple components can share the state, which is better for management and maintenance.