The five core concepts of VUex:

  • State: Shared State. Vuex’s basic data is used to store variables, which are equivalent to the data in the component data, but now become global variables.

  • Getter: Derived state based on state, equivalent to a property in computed in the component.

  • Mutation: The method of changing the shared state of store in VUEX is to modify the state by submitting mutation to synchronize operation data. It is usually used for action to obtain asynchronous data, and to obtain data submitted to mutation through COMMIT and in the state of mutation synchronization operation.

  • Action: Supports asynchronous operations, which can be used to asynchronously obtain the data in the request and commit the obtained data synchronously to mutation, implementing ajax asynchronous request data, and mutation synchronizes its data to state.

  • Modules: VuEX. In order to facilitate the later project management, each module can have its own state, mutation, action and getters, which makes the structure very clear and easy to manage.

Vuex uses the core management warehouse to build the Store

This new store folder, create a named js index, js, in the index, by the state, mutations, the actions, getters is introduced into the store, and exposed the store object.

Here is the code for index.js

/* store */ import Vue from 'Vue '; import Vuex from 'vuex'; Import state from './state'; import state from './state'; import mutations from './mutations'; import actions from './actions'; import getters from './getters'; / / declare use plug-in Vue. Use (Vuex) / / new a Vuex object, will state, mutation, action, getters configuration to Vuex store, convenient management, data export default new Vuex.Store({ state, mutations, actions, getters, })Copy the code

Mount store to vue instance main.js

import store from './store'
// ..........
new Vue({
  el: '#app',
  router,
  store,   // ***
  render: h => h(App)
})
Copy the code

State Indicates status management data

We typically place shared data that needs to be managed in state, making it look like a global variable, and import the state data for the components that need it.

**

const state = {
  userId: '',
  token: '',
  name: '',
  avatar: '',
  introduction: '',
  roles: [],
  tenantId: 1,
  userInfo: null
};
Copy the code

Mutations simultaneously submit the data

Mutations is used to change the state logic in state and synchronously change the state data in state. It should be noted that only mutation can modify the state object in VUEX. The state can be modified by obtaining data obtained from actions, or the status data can be changed by directly defining methods in the Mutations module.

**

const mutations = { SET_TOKEN: (state, token) => { state.token = token; }, SET_USERID: (state, userId) => { state.userId = userId; }, SET_NAME: (state, name) => { state.name = name; }, SET_ROLES: (state, roles) => { state.roles = roles; }, SET_TENANTID: (state, roles) => { state.tenantId = roles; }, SET_USER_INFO: (state, userInfo) => { state.userInfo = userInfo; }};Copy the code

Mutations and the actions module below also show that commit is used to call the mutation module. The code for calling its mutation module in the component is:

this.$store.commit('SET_TOKEN', token_data) 
Copy the code

Asynchronous actions

Actions is similar to mutations, but it can operate asynchronously and submit the data obtained by the asynchronous operation to mutations, causing mutations to change the state data in state, which is often used to obtain data in Ajax requests (because it is asynchronous). Commit the obtained data and submit it to mutations to update the state of the data.

The differences with mutations are as follows:

  1. The Action commits mutation rather than a direct state change.
  2. Actions can contain any asynchronous operation.

For example,

/ * this is through the actions to perform asynchronous Ajax request, after get the data, through the commit method call mutations to update the data For example: the commit (' SET_TOKEN 'data. Uuid); */ const actions = {login({commit}, userInfo) {// User login const params = userInfo; params.userName = userInfo.userName.trim() return new Promise((resolve, reject) => { getLogin(params) .then((response) => { const { status, message, data } = response || {}; If (status === 200) {// Save parameter: 1. 2. Commit ('SET_USER_INFO', data); commit('SET_TOKEN', data.uuid); commit('SET_USERID', data.id); commit('SET_ROLES', data.roles); commit('SET_NAME', data.realName); commit('SET_TENANTID', data.tenantId || 1); setToken(data.uuid); db.save('userInfo', data); db.save('tenantId', data.tenantId || 1); localStorage.setItem('loginToken', data.uuid); resolve(data); } else { // ElementUI.Message.error(message); }}). Catch ((error) => {// elementui.message.error (error.message); // Axios reject(error); }); }); }},Copy the code

The actions call method in the component is:

this.$store.dispatch('user/login', postUser) .then(res => { // ............. }) // my login method is written in the user.js module, so the call is user/login // we'll talk about module belowCopy the code

Getters processes state

Getters is equivalent to computed attributes and is used to process state state data. It has two default parameters, the first is state and the second is Getters.

Const getters={plusCount(state){return state.count + 1}, TotalCount (state,getters){return getters.pluscount + state.count}}Copy the code

The code snippet for calling this method in a component is:

this.$store.getters.totalCount()
Copy the code

Get the Vuex state in the Vue component

The easiest way to read state from a Store instance is to return a state in a calculated property. Since Vuex’s state store is reactive, the calculated property is refetched whenever store.state.count changes for a reactive update.

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

So we have briefly introduced the store above, I believe you will have a certain understanding of VUex after reading it. This.$store.state or this.$store.getters. Let’s look at another way to introduce states and getters

Auxiliary functions mapState and mapGetters

Bothered by the above method of referring to state and getters in the component? You will find it convenient to use mapState. Component is used this way

Import {mapGetters,mapState} from 'vuex' export default {computed: {// Use the object expansion operator to mix getters into a computed object... MapGetters (['plusCount','totalCount']) // Mix state in a computed object using the object expansion operator... mapState( ['userInfo','count'] ) }, Methods :{getData(){this.userinfo // this.pluscount}}}Copy the code

Module Sub-module management

The code for index.js in the store folder is as follows

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)


const modulesFiles = require.context('./modules', true, /.js$/)


const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  const moduleName = modulePath.replace(/^./(.*).\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store
Copy the code

The file directory is shown in figure

For example, the API. Js

import { getKey, getLogin, logout, getInfo } from '@/api/user'; import { setToken, removeToken } from '@/utils/auth'; import db from '@/utils/localstorage'; import router, { resetRouter } from '@/router'; import ElementUI from 'element-ui'; const state = { userId: '', token: '', name: '', avatar: '', introduction: '', roles: [], tenantId: 1, userInfo: null // roles: ['9999'] }; const mutations = { SET_TOKEN: (state, token) => { state.token = token; }, SET_USERID: (state, userId) => { state.userId = userId; }, SET_NAME: (state, name) => { state.name = name; }, SET_ROLES: (state, roles) => { state.roles = roles; }, SET_TENANTID: (state, roles) => { state.tenantId = roles; }, SET_USER_INFO: (state, userInfo) => { state.userInfo = userInfo; }}; Const Actions = {// get the key getKey({commit}) {return new Promise((resolve, resolve, reject) => { getKey() .then((response) => { resolve(response); }) .catch((error) => { reject(error); }); }); }, // login({commit}, userInfo) {// const {username, password} = userInfo; const params = userInfo; params.userName = userInfo.userName.trim() return new Promise((resolve, reject) => { // console.log(username, password);  // setToken(state.token) // localStorage.setItem('loginToken', state.token) getLogin(params) // getLogin({ userName: username.trim(), password: password }) .then((response) => { const { status, message, data } = response || {}; If (status === 200) {// Save parameter: 1. 2. Commit ('SET_USER_INFO', data); commit('SET_TOKEN', data.uuid); commit('SET_USERID', data.id); commit('SET_ROLES', data.roles); commit('SET_NAME', data.realName); commit('SET_TENANTID', data.tenantId || 1); setToken(data.uuid); db.save('userInfo', data); db.save('tenantId', data.tenantId || 1); localStorage.setItem('loginToken', data.uuid); resolve(data); } else { // ElementUI.Message.error(message); }}). Catch ((error) => {// elementui.message.error (error.message); // Axios reject(error); }); }); GetInfo ({commit, state}) {return new Promise((resolve, resolve)) reject) => { getInfo(state.token) .then((response) => { const { data } = response; data.roles = response.data.rights.map(String); if (! Data) {reject(' Authentication failed, please log in again. '); } const loginMessage = { memberId: data.id, userName: data.name, userTel: data.mobile, realName: data.realName, incorCom: data.incorCom, virtualCor: data.virtualCor, deptId: data.deptId, deptpath: data.deptpath, deptName: data.deptName }; localStorage.setItem('loginMessage', JSON.stringify(loginMessage)); const { id, roles, realName } = data; // The role must be a non-empty array! if (! Roles | | roles. Length < = 0) {reject (' getInfo: the character must be a empty array! '); } commit('SET_USERID', id); commit('SET_ROLES', roles); commit('SET_NAME', realName); localStorage.setItem('userRights', roles); // commit('SET_AVATAR', avatar) // commit('SET_INTRODUCTION', introduction) resolve(data); }) .catch((error) => { reject(error); }); }); }, // User logout({commit, state}) {return new Promise((resolve, resolve) reject) => { logout(state.token) .then(() => { commit('SET_TOKEN', ''); commit('SET_ROLES', []); db.remove('router'); removeToken(); resetRouter(); resolve(); }) .catch((error) => { reject(error); }); }); }, // Delete token resetToken({commit}) {return new Promise((resolve) => {commit('SET_TOKEN', ''); commit('SET_ROLES', []); removeToken(); resolve(); }); }, // Change permissions dynamically changeRoles({commit, dispatch}, role) { return new Promise(async(resolve) => { const token = role + '-token'; commit('SET_TOKEN', token); setToken(token); const { roles } = await dispatch('getInfo'); console.log(roles, 'rolesrolesroles'); resetRouter(); / / accessible route map was generated according to role const accessRoutes = await dispatch (' permission/generateRoutes' roles, {root: true}); Router.addroutes (accessRoutes); // Reset visited views and cached views dispatch('tagsView/delAllViews', null, {root: true}); resolve(); }); }}; export default { namespaced: true, state, mutations, actions };Copy the code

In this way, it can be called in the page by function module

Use mutations this. codestore.com MIT (' API /SET_T', keys); // Actions this.$store.dispatch('user/login', Use this. Codestore.com MIT ('SET_T', keys); // Call the method directlyCopy the code
  • Reprinted www.jianshu.com/p/47fdec415…