After the introduction of VUEX, we need to define variables in state, similar to data in VUE, to store the state through state

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
exportDefault new vuex. Store({state: {nickname: nickname: nickname)'Simba',
    age:20,
    gender:'male'
  },
  mutations: {},
  actions: {},
  modules: {}
})
Copy the code

Register two components to be imported into app.vue separately

<div id="app"> </vabout> </vabout> </vhome> </vhome> <div class="home"> {{$store.state. Nickname}}</div> <h1>{{$store.state.nickname}}:{{$store.state.age}}</h1>
Copy the code

With Vuex, you don’t have to worry about passing values between components. Instead, you can use $store to get different data, but if you need more than one piece of data in vuex, you can define it on computed.

The initialization of Props, methods,data, and computed is done between beforeCreated and created.

Ex. :

<template>
  <div class="home">
    {{nickname}}
  </div>
</template>
<script>
export default {
  name: 'home',
  computed:{
    nickname() {return this.$store.state.nickname
    }
  }
}
</script>
Copy the code

That’s a lot easier to introduce.

Although the methods in 1.1 were introduced to be convenient, there is still a lot of code defined in computed, and vuex provides us with a simpler method called mapState

import {mapState} from 'vuex'
export default {
  name: 'home',
  computed: mapState(['nickname'.'age'.'gender'])}Copy the code

MapState ([‘nickname’,’age’,’gender’]) // Insert ‘nickname’ (‘nickname’,’age’,’gender’

nickname() {return this.$store.state.nickname}
age() {return this.$store.state.age}
gender() {return this.$store.state.gender}
Copy the code

Remember: when using helper functions such as mapState, the method name is the same as the property name.

What if we need to customize a computed property? How do we add it?

Computed: mapState([‘nickname’,’age’,’gender’])

This is where we need the expansion operator in ES6:…

Computed: {// For computed, parameters cannot be passedvalue() {returnthis.val/7 }, ... mapState(['nickname'.'age'.'gender'])}Copy the code

Getters is equivalent to the calculated attribute in VUE. Through getters further processing, we can get the value we want. Moreover, parameters are allowed to pass, and the first parameter is state

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
 
exportDefault new vuex. Store({state: {nickname: nickname: nickname)'Simba',
    firstname:'张',
    lastname:'sanfeng',
    age:20,
    gender:'male',
    money:1000
  },
  getters:{
    realname(state){
      return state.firstname+state.lastname
    },
    money_us(state){
      return (state.money/7).toFixed(2)
    }
  },
  mutations: {},
  actions: {},
  modules: {}
})
Copy the code

Vue part

Computed: {// For computed, parameters cannot be passedvalued() {returnthis.value/7 }, ... mapGetters(['realname'.'money_us'])}Copy the code

Mutations 3.1 We need some mutations when defining in our code, which is similar to methods in VUE,

Mutations requires a commit to call the method in it, and it can also pass in parameters, the first parameter is state, and the second parameter is payLoad, which is an additional parameter

The following code

Mutations: {// similar to methods addAge(state,payLoad){state-.age += payment.number}}Copy the code

Template section

<div class="home">
   <div><button @click="test"</button></div> </div>Copy the code

Js part

methods:{
 test(){
   this.$store.commit('addAge',{
     number:5
   })
 }
}
Copy the code

It’s better to write the second argument as an object when calling, so we can pass more information.

But, again, you have the same problem, which is that if you have to manipulate more than one piece of data, it becomes troublesome, and that’s when you need mapMutations, which maps the method over

MapMutations is the same as mapState and mapGetters

methods:{ ... mapMutations(['addAge'])
}
mapMutations(['addAge']) = addAge(payLoad){this.$store.commit('addAge',payLoad)
}
Copy the code

Parameter that we can write when we call this method

<button @click="addAge({number:5})"> test < / button >Copy the code

At this time, some refiners need to say, why should I go around and change the state through mutations? Can I just change state?

Like this:

addAge(){
 this.$store.state.age +=5;
}
Copy the code

Actually, the results can also be seen, so why do I change from mutations inside?

Here’s why:

And ① you can do more than just an assignment operation in mutations

(2) The author performs similar burial operation in mutations. If the operation can be detected from mutations, it is more convenient to use debugging tools, which can detect real-time changes, but cannot be monitored in real time if the properties in state are directly changed

Note: Mutations can only write synchronous methods, not asynchronous ones, such as Axios, setTimeout, etc., which can’t be written, and their main role is to modify state.

The reasons are similar: if asynchronous is written in mutations, the adjustment can be successful, but because it is asynchronous and cannot be tracked by the debugging tool, it is not recommended to write this, which is not good for debugging. This is the official agreement.

3.3 Using constant Replacement of the Mutation event type converts the original method name from string to constant

The code is as follows:

import Vue from 'vue'
import Vuex from 'vuex'
export const ADD_AGE ='addAge' 
Vue.use(Vuex)
exportDefault new vuex. Store({state: {nickname: nickname: nickname)'Simba',
    firstname:'张',
    lastname:'sanfeng',
    age:20,
    gender:'male', money:1000}, getters:{// similar to computed RealName :state =>state.firstname+state.lastname, money_us(state){return(state.money/7).toFixed(2) } }, mutations: {// Similar to methods [ADD_AGE](state,payLoad){state. Age +=payLoad. Number}}, actions: {}, modules: {}})Copy the code

Define the addAge method name as a constant that will be introduced directly when called

import {ADD_AGE} from '.. /store'
import {mapMutations} from 'vuex'
exportdefault { methods:{ ... mapMutations([ADD_AGE]) } }Copy the code

Benefits of writing like this:

(1) it is not easy to write wrong, string easy to write wrong, and string won’t wrong position error, and with constant replacement, if write wrong, eslint can prompt error

Instead of constants, we can create a new file (mutation_type. Js) that stores these constants

Mutation_type. Js part

exportDefault {ADD_AGE: 'addAge'}Copy the code

Then introduce it in store/index.js

Import MUTATION_TYPES from './mutation_type 'export letMUTATION_TYPE=MUTATION_TYPESCopy the code

There is a pit here, do not combine import and export into a single line of code: for example

export { foo, bar } from 'my_module'; // Import {foo, bar} from'my_module';
export { foo, bar };
Copy the code

Note that foo and bar are not the same as each other. Once written in a single line, foo and bar are not actually imported into the current module. They are just forwarded to the external interface, so that the current module cannot directly use foo and bar.

Vue part

import {MUTATION_TYPE} from '.. /store'methods:{ ... mapMutations([MUTATION_TYPE.ADD_AGE]) }Copy the code

To summarize:

(1) use getters (read-only like computed) to obtain new data

Mutations (synchronous operation) is used to modify the attribute value of state.

Actions 4.1 Action is similar to mutation

Differences: An action can submit an mutation

Action also does not directly operate on state, but on mutation

Actions contain asynchronous operations, similar to AXIos requests, that can be written in an action

Methods in action are asynchronous by default and return promises

The following code

Store part

actions: {
  getUserInfo() {return {
      nickname:'Simba',
      age:20
    }
  }
}
Copy the code

Define a method in actions: getUserInfo, and return an object

Vue part

created(){ var res = this.getUserInfo() console.log(res) }, methods:{ ... mapActions(['getUserInfo'])}Copy the code

Call this method in created, assign the result to res, print the RES, and print the Promise

This indicates that methods in actions, which are asynchronous by default, get data via THEN

MapActions ([‘getUserInfo’]) corresponds to the following code

getUserInfo() {return this.$storeDispatch (' getUserInfo)}Copy the code

In actual development, the value of the property in state is empty. After login, the corresponding information is obtained.

After login, you need to get the user information, so how to get it?

First, the getUserInfo method in the Actions is called when the page is entered

The following code

Vue part

created(){ this.getUserInfo()} methods:{ ... MapActions ([' getUserInfo])}Copy the code

Store part

The first thing that comes to mind is that you want to get the data, which is equivalent to valuing state, and the first thing that comes to mind is that they’re manipulating state, but the interfaces that are requested are axios asynchronous, so you can’t use mutations, you can use actions, Mutations are manipulated through actions to operate state

exportDefault new vuex. Store({state: {nickname: ' ', age:0, gender:' ', money:0 }, mutations: { setUerInfo(state,payLoad){ state.nickname = payLoad.nickname state.age = payLoad.age state.gender = payLoad.gender Money = payLoad. Money}}, actions: {//actions does not provide state when the parameter async getToken({commit}){var res = await axios.get('/ token interface')
   commit('setToken',res)}, async getUserInfo(context){// Context can be interpreted as an object of the entire Store. Similar to this.$storeMutations, actions const res = await and axios.get().'/ interface url')
  context.commit('setUerInfo',res) // equivalent to this.$storeCommit, the first argument is the method name, and the second argument is the data to be passed in context.dispatch('getToken') // Actions can also call their own methods},}})Copy the code

Run the procedure, call getUserInfo, go to actions, then call setUserInfo with commit, pass in res (user information) as an argument, and assign the corresponding attribute value to state to complete the process.

The getUserInfo parameter can also be deconstructed for convenience

async getUserInfo({commit,dispatch}){ 
  const res = await axios.get('/ interface url')
  commit('setUerInfo',res) 
  dispatch('getToken')}Copy the code

From:zhuanlan.zhihu.com/p/100941659