1. Vuex installation

【 NPM 】

npm install vuex --save
Copy the code

“Yarn”

yarn add vuex
Copy the code

[Remarks] Sometimes when the component Vue project is created, Vuex has been installed synchronously when the project is created, and the corresponding file directory structure is created. There is no need to install Vuex separately. The first half of the current content is based on a separate Vuex installation.

【 Key Concepts 】

  1. State
  2. Getters
  3. Mutations
  4. Actions
  5. Modules

2. Vuex initialization

[2.0] Create store folder and create index.js file. (This file is responsible for introducing specific module content)

// Automatic module import under folder

import Vue from 'vue';
import Vuex from 'vuex';
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
}, {})
export default new Vuex.Store({
  modules
});
Copy the code
// It is easy to understand
import Vue from 'vue'
import Vuex from 'vuex'
import common from './modules/common'
import user from './modules/user'
import article from './modules/article'
import message from './modules/message'
import wxUserTags from './modules/wxUserTags'
import wxAccount from './modules/wxAccount'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    common,
    user,
    article,
    message,
    wxUserTags,
    wxAccount
  },
  mutations: {},strict: true
})
Copy the code

[2.1] Create various module JS files (such as common, user, article, etc.)

/ / for example 1
const state = { 
	userinfo: ' '.token:"".loginInfo: [].// The initial property value to set
};
// Monitor state changes in real time
const getters = { 
	getuserinfo(state) { // The method name is arbitrary, mainly to carry the value of the changing userinfo
		return state.userinfo
	},
	gettoken(state){
		return state.token
	},
	getloginInfo(state){
		return state.loginInfo.lenth==0 ? state.loginInfo : JSON.parse(localStorage.getItem("loginInfo"))}};// The first parameter does not have a default parameter
Use this. Codestore.com MIT ('')
const mutations = {
	ChangeUserinfo(state, userinfo) { // Define the method to change the initial value of state, where the parameters can be passed additional parameters (variables or objects) in addition to state;
		state.userinfo=userinfo
	},
	Changetoken(state, token) { 
		state.token=token
	},
	ChangeloginInfo(state, loginInfo) { 
		state.loginInfo=loginInfo
		window.localStorage.setItem("loginInfo".JSON.stringify(state.loginInfo)); }};// Async, execute this.$store.dispatch(" ")
 const actions = {
    ChangeUserinfo(context,userinfo) {  // Customize the method that triggers the function in mutations. Context and store instances have the same methods and attributes
        context.commit('ChangeUserinfo',userinfo);
    },
	Changetoken(context,token) {
		context.commit("Changetoken", token)
	},
	ChangeloginInfo(context,loginInfo) {
		context.commit("ChangeloginInfo", loginInfo)
		
	},
};
export default {
     //namespaced:true,// identifies the file name when globally referencing methods in this file
     state,
     getters,
     mutations,
     actions
}
Copy the code
/ /, for example - 2
export default {
  // Whether the module name is required to obtain the attribute
	namespaced: true.// 
	state: {
		id: 0.name: 'Zhang SAN Feng'.nameLsit: [{name: '张'.age: 21
			},
			{
				name: 'the king'.age: 22
			},
			{
				name: 'li'.age: 23
			},
			{
				name: '赵'.age: 24}},],// 
	getters: {
		getName(state) {
			return state.name
		},
		findName: (state) = > (name) = > {
			return state.nameLsit.find(nameLsit= > nameLsit.name === name)
		},
		addUserid(state) {
			return state.id + 1}},// 
	mutations: {
		updateId(state, id) {
      		state.id = id
    	},
    	updateName(state, name) {
      		state.name = name
    	}
	},
  // 
  actions: {}}Copy the code

3.state,mapState,… MapState object expansion

[3.1] Attribute access

this.$store.state.user.name // user specifies the module name
Copy the code

[3.2] Calculate attributes – Read status values

computed: {
    name () {
      return this.$store.state.user.name
    }
},
/ / read
methods: {
  changname(){
    console.log('-- -- -- -- -- -- -- -- -- -- -- -- --');
    console.log('-- -- -- -- -- -- -- -- -- -- -- -- --' + this.name);
    console.log('-- -- -- -- -- -- -- -- -- -- -- -- --' + this.$store.state.user.name); }},Copy the code

When page assignments are made, values in the state class in Vuex can be directly assigned to data, as follows

data() {
    return {
      name: this.$store.state.user.name 
    }
  },
Copy the code

(However, this value cannot be changed dynamically because it does not change all the time. Therefore, it is computed.)

[3.3]mapStateAuxiliary function

// In the separately built version, the auxiliary function is vuex.mapstate
import { mapState } from 'vuex'

export default {
  // ...
  computed: mapState({
    // Arrow functions make code more concise
    count: state= > state.count,

    // Pass the string argument 'count' equal to 'state => state.count'
    countAlias: 'count'.// In order to be able to use 'this' to get local state, you must use regular functions
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}
Copy the code

[3.3] mapStateAuxiliary functions – Object expansion operators

// namespaced: false,. mapState({nameMap: state= > state.name
}),
/ / or. mapState('user', {nameMap: 'name'
}),
  
// namespaced: true,. mapState('user', {nameMap: state= > state.name
}),
/ / or. mapState('user', {nameMap: 'name'
}),
    
/ / use
console.log(The '-' + this.nameMap)
Copy the code

4.getters,mapGetters,… MapGetters,

getters: {
    getProductByid: (state) = > (id) = >
    {
        return state.productList.find(item= >item.id === id); }}Copy the code

[3.1] Attribute access

When namespace is used:

this.$store.getters['yournamespace/getProductByid'](id);
Copy the code

When namespace is not in use:

this.$store.getters.getProductByid(id);
Copy the code

[3.2] Access by method

computed: {
  getName_C() {
    return this.$store.getters['user/getName'];
  },
  getName_Changer() {
    return function (value) {
      return this.$store.getters['user/findName'](value); }}},methods: {
    getName(){
      console.log('-- -- -- -- -- -- -- -- -- -- -');
      console.log(The '-' + JSON.stringify(this.$store.getters['user/findName'] ('li')))
      console.log(The '-' + JSON.stringify(this.getName_Changer('张')))
      console.log(The '-' + this.getName_C); }},Copy the code

【 3.3 】mapGettersAuxiliary function

// namespaced: false,. mapGetters({userIds: 'addUserid'
})

// namespaced: true,. mapGetters('user', {userIds: 'addUserid'
})

/ / use
console.log(The '-' + this.userIds)
Copy the code

5.Mutation

Mutations, as widely understood, contain a set of methods for changing data. This is an important point in Vuex design, which is to put all the logical methods for processing data into mutations, separating data and view. Remember: the only way to change store data in Vuex is mutation!

The only way to change the state in Vuex’s store is to submit mutation. This is the text of the official document. It is critical not to change the state in the Store in any other way, as doing so would take the state out of our control.

Mutation in Vuex is very similar to the $emit event in VUE,

  • Each mutation has a string of event type, which is a unique identifier for the current event, so you can trigger it with commit.

  • Each mutation has a callback function (handler). This callback is where we actually make the state change, and it accepts state as the first argument. It also supports passing in extra parameters, the term for which is’ payload ‘.

[Example analysis – Column 1 (Common)]

Define a mutation in stroe that will count++.

mutations:{
	addCount(state){ state.count++; }},Copy the code

The first parameter of mutation is state, from which we can retrieve the state defined in state.

/ / call
methods: {addCountInR1(){
    this.$store.commit("addCount"); }}Copy the code
// namespaced: false,
this.$store.commit('updateName', nameNew);

// namespaced: true,
this.$store.commit('user/updateName', nameNew);
Copy the code

【mapMutations auxiliary function 】

// namespaced: false,. mapMutations(['updateName',),... mapMutations({onUpdateName: 'updateName'
}),
// namespaced: true,. mapMutations('user'['updateName',),... mapMutations('user', {onUpdateName: 'updateName' 
}),
Copy the code

[Example analysis – Column 2 (parameter)]

To mutation, you may need to pass in parameters when changing the state in the store. To define a mutation: addCountWithParams, implementation will count the value of the combined with the parameters of the transmission.

mutations:{
	addCount(state){
		state.count++;
	},
	addCountWithParams(state, params){
		state.count += params;
	},
	pushDataToArrat(state){
		state.array.push({
			name:"sunq".age:100})}},Copy the code

Component pass parameter calls

methods:{
    addCount(){
        this.$store.commit("addCountWithParams".Math.ceil(Math.random() * 20)); }},Copy the code

Pass in a random integer from 1 to 20 and add to count.

The official recommendation is to pass an object parameter, and this is true in practice. This avoids the need to control the number of parameters, and can be used in combination with the submission of mutation objects.

mutations:{ addCount(state){ state.count++; }, addCountWithParams(state, params){ state.count += params; }, addCountWithObjParams(state, params){ state.count += params.num; }},Copy the code

Call addCountWithObjParams using an object in the component.

methods:{
    addCount(){
        // Submit in normal mode
        this.$store.commit("addCountWithObjParams", {
            num: Math.ceil(Math.random() * 10)});// Submit in object mode
        this.$store.commit({
            type: "addCountWithObjParams".num: Math.ceil(Math.random() * 10)}); }},Copy the code

The code above is submitted twice, using normal and object style addCountWithObjParams.

6. Action

Action is similar to mutation, except that:

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

【 句 型 -1】

// Async, execute this.$store.dispatch(" ")
 const actions = {
    ChangeUserinfo(context,userinfo) {  // Customize the method that triggers the function in mutations. Context and store instances have the same methods and attributes
        context.commit('ChangeUserinfo',userinfo);
    },
	Changetoken(context,token) {
		context.commit("Changetoken", token)
	},
	ChangeloginInfo(context,loginInfo) {
		context.commit("ChangeloginInfo", loginInfo)
		
	},
};
Copy the code

【 作 文 名 称 】

const store = new Vuex.store({
// Define state/mutations/actions and so on here, and all of them are in object form
	state: {num:0
	},
	mutations: {numPlusVar(state,var){
			state.num += var}},actions: {The first argument, context, represents the current store instance. The status can be accessed using context.state, or submit mutations using context.com, MIT. Other actions can also be called by context.diapatch
		asyncAddNum(context,var){
			 setTimeout(function(){
     	 	  // After one second, modify state with num as the parameter
     	 	  context.commit('numPlusVar'.var)},1000)}}})Copy the code

[6.1] Attribute access

// html
<template>
  <div>{{ num }}</div>/ / 0
	<button @click="asyncChange">Asynchronously modify using the original dispacth method</button>
</template>

// Js
<script>
import { mapState } from "vuex";
export default {
	computed: {
		...mapState(["num"])},methods: {1 / / method
		asyncChange(){
      // namespaced: false,
			// After one second +10
			this.$store.dispatch('asyncAddNum'.10)
      // namespaced: true,
      this.$store.dispatch('Module name /asyncAddNum'.10)}}}Copy the code

[6.2] mapActions auxiliary functions

// html
<template>
 		<div>{{ num }}</div>/ / 0
		<button @click="asyncAddNum(100)">Make the changes asynchronously using the mapActions method</button>// After one second +100
</template>

// Js
<script>
import { mapState, mapActions } from "vuex";
export default {
	computed: {
		...mapState(["num"])},methods: {2 / / method
    // namespaced: false,. mapActions(['asyncAddNum']),
    // namespaced: true,. mapActions('Module name'['asyncAddNum']),
    / / or. mapActions('Module name', {alias:'asyncAddNum'}}}),Copy the code