Definition 1.

Vuex is a state management mode 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 way

  • State, the data source that drives the application;
  • View, to declaratively map state to the view;
  • Actions, in response to changes in state caused by user input on the view.

2. Install

vue add vuex
Copy the code

Use 3.

Use the matution operation state directly

<script>
//1.1 Direct definition
//src/store/index.js
export default new Vuex.Store({
   state: { isLogin: false },
   mutations: {
       login(state) {
          state.isLogin = true;
       },
       logout(state) {
          state.isLogin = false; }},})//1.2 Modular definition
//src/store/user.js
export default {
  state: { isLogin: false },
  mutations: {
   login(state) {
      state.isLogin = true;
   },
   logout(state) {
      state.isLogin = false; }},}//src/store/index.js
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
  modules: {
    user
  },
})

/ / 2. Use
//main.js
import store from './store'
new Vue({
  router,
  store,
  render: h= > h(App)
}).$mount('#app')
  
/ / login. Vue calls
<template>
  <button @click="login" v-if=! "" $store.state.isLogin">The login</button>
  <button @click="logout" v-else>logout</button>
</template>

this.$store.commit('login') 
this.$store.commit('logout')

Copy the code

4. Common objects

4.1 the State

const app = new Vue({
  el: '#app'.// Provide the store object to the "store" option, which injects store instances into all child components
  store,
  components: { Counter },
  template: ` 
      
`
}) // Child components can be accessed directly by this this.$store.state.count Copy the code

4.2 mapState

Advantages: Can simplify long access to defined namespaces, such as this.$store.user. XXX definition: default return key value heap way

data () {
    return {
      username: 'Joe'}},// Method 1 uses mapState
// The shortcoming occupies the entire computed tag, and the original computed outer layer has to be modified
computed: mapState({
    count: 'count'.// The first way
    sex: (state) = > state.count, // The second way
    from: function (state) { // Use the normal function this to point to the vue instance, beware
      return this.username + ':' + state.count
    },
  }), 
// Method 2 uses... MapState // Deconstruction makes computed: retains the original outer deconstruction
// Before use
computed: {fn1(){ return. },fn2(){ return. },fn3(){ return. }}// The outer structure remains unchanged after use
computed: {// Keep the original
    fn1(){ return. },fn2(){ return. },fn3(){ return. }// Maintain vuex again. mapState({// Mix it with an extension to the current computed object
        count:'count'})}Copy the code

4.3 Mutation

State can only be modified by mutation, which must be a synchronization function

/ / define
mutations: {
    login(state) {
      state.isLogin = true;
    },
    logout(state) {
      state.isLogin = false; }},/ / call
this.$store.commit('login') 
this.$store.commit('logout')
Copy the code

4.4 the Getter

You can use getters to derive some state from the store’s state and update the derived state synchronously if state changes, just as with computed

export default { 
    state: { 
        isLogin: false.username: ' ' / / user name
    },
   getters: { // This property is obtained in the same way as state
       welcome: state= > { return state.username + 'Welcome back'; }},Copy the code

4.5 the Action

Action is similar to mutation, except that:

  1. Mutation is committed, not a direct state change.
  2. Can contain any asynchronous operation.
export default { 
  state: {
    isLogin: false.username: ' '
  },
  actions: {
      login({ commit }, username) {
        return new Promise((resolve, reject) = > {
          setTimeout(() = > {
            if (username === "admin") {
              commit("login"); // Submit mutation via comIMT
              resolve();
            } else{ reject(); }},1000); }); }},// Dispatch the action via dispatch
 this.$store.dispatch("login"."admin")
      .then(() = > {
        this.$router.push(this.$route.query.redirect);
      })
      .catch(() = > {
        alert("Wrong username or password");
      });
Copy the code

4.6 mapMutation ()/mapAction ()

Automatically map $store methods to avoid direct access to $storeCopy the code

 //mapMutations uses method 1. mapMutations(['login'./ / will ` enclosing the login () ` mapping for ` this.$store.com MIT ` (" login ")
]),
//mapMutations uses method 2. mapMutations({login: 'login'/ / will ` enclosing the login () ` mapping for ` this.$store.com MIT ` (" login ")
})

//action Related modifications
import { mapActions } from 'vuex' 
//1. With namespaces, disadvantages and computed names are indistinguishable
methods: { 
    login() { 
        this['login'] ('admin').then(...) 
    }, 
    ...mapActions('user'['login']) // The destruct method is injected into the current methods object
},

//1. Use this[' XXX /xx'] as the direct name
methods: { 
    login() { 
        this['user/login'] ('admin').then(...) 
    }, 
  ...mapActions(['user/login'])},Copy the code

4.6 Strict Mode

In strict mode, an error is thrown whenever a state change occurs that is not caused by a mutation function. This ensures that all state changes are tracked by the debugging tool. Enable strict mode: true

export default new Vuex.Store({
  modules: {
    user
  },
  strict: true,})Copy the code

4.7 Defining a namespace

//src/store/user.js
export default {
  namespaced: true.// Set up a separate namespace to avoid naming conflicts with user/ XXXX./ / define
  mutations: {
    login(state) {
      state.isLogin = true;
    },
    logout(state) {
      state.isLogin = false; }},}/ / introduction
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
  modules: {
    user
  },
})
/ / call
this.$store.state.user.isLogin
this.$store.commit('user/login') 
this.$store.commit('user/logout')
Copy the code

4.8 plug-in

Vuex’s store accepts the plugins option, which exposes the hook for each mutation. The Vuex plugin is a function that accepts store as the only parameter: Requirement: Every time the page is refreshed, the information of the user who logged in before can be normally read and set to the current $Store information

const myPlugin = store= > {
// called when store is initialized} Register plugins:const store = new Vuex.Store({
   // ... 
   plugins: [myPlugin],
});

// Implement login state persistence, store/plugins/persist
export default (store) => {
      // Get data from localStorage during initialization
      if (localStorage) {
        const user = JSON.parse(localStorage.getItem("user"));
        if (user) {
          store.commit("user/login");
          store.commit("user/setUsername", user.username); }}// Cache it when the user state changes
      store.subscribe((mutation, state) = > {
        if (mutation.type.startsWith("user/")) {
          localStorage.setItem("user".JSON.stringify(state.user));
        } else if (mutation.type === "user/logout") {
          localStorage.removeItem("user"); }}); }; }Copy the code