vue from introduction to mastery [vuex]

Posted by contex on Mon, 03 Jan 2022 00:00:59 +0100

vue from introduction to mastery [vuex] (VII)

Vuex is a large public warehouse. Vuex can help us manage shared state, with more concepts and frameworks.

Vuex implements a one-way data flow. It has a state to store data globally. When a component wants to change the data in the state, it must do so through changes. Changes also provides a subscriber mode for external plug-ins to call to obtain the update of state data. When all asynchronous operations (commonly used to call the back-end interface to obtain data asynchronously) or batch synchronous operations need to go through actions, but actions cannot directly modify the state, you still need to trigger the methods in changes and then modify the state data through changes. After the data is changed, it is pushed to the component, and the component is re rendered to the view.

Vuex is the state manager of vue, and the stored data is responsive. But it will not be saved. After refreshing, it will return to the initial state. The specific method is to copy and save a copy of the data in vuex to localStorage when the data changes. After refreshing, if there is saved data in localStorage, take it out and replace the state in the store.

Core: State, Getter, Mutation, Action, Module

  1. state: contains the states stored in the store.
  2. getter: similar to the calculation property in Vue, the return value is calculated according to other getters or state s.
  3. mutation: a group of methods, which are the executors of changing the state in the store. They can only be synchronous operations.
  4. action: a set of methods that can contain asynchronous operations.
  5. module: modular management

1, Installation

npm install vuex --save
yarn add vuex

2, Create warehouse

Create a store folder under src and an index js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0,
    name:"zhangsan"
  },
  getter: {
    doneTodos: (state, getters) => {
      return state.todos.filter(todo => todo.done)
    }
  },
  mutations: {
    increment (state, payload) {
      state.count++
    }
  },
  actions: {
    addCount(context) {
      // Can include asynchronous operations
      // Context is a context object with the same methods and properties as the store instance
    }
  }
})

export default store;

Modify main js:

import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // Introduce the store object we exported earlier

Vue.config.productionTip = false;

new Vue({
    el: '#app',
    router,
    store, // Add the store object to the vue instance
    components: { App },
    template: '<App/>'
});

Finally, modify app vue:

<template>
    <div></div>
</template>

<script>
    export default {
        mounted() {
            // Use this$ store. state. XXX has direct access to the status in the warehouse
            console.log(this.$store.state.name); 
        }
    }
</script>

At this point, start the project npm run dev to output the value of name we just defined in the store on the console.

3, Use

State is similar to data in vue

Vuex uses state to store the state that needs to be shared in the application. In order to make Vue components change after the state is changed, you need to create calculated properties based on the state.

const state = {
  count:"",
  storeId:"",
  storeName:''
}

1. Use

{{this.$store.state.count}} (no cache, do not use)

2.computed (with cache)

If the data is not updated, go to the cache to get the latest data

computed: {
     //It has the function of data cache
     count() {
       return this.$store.state.count;
}}

3.mapState auxiliary function

//Import
import { mapState } from 'vuex'				 
				 
computed:mapState(["count","num","apple"])
				 
computed:mapState({
		c:state => state.count,
			n:"num",
			result(state){
			return state.count + state.num 
			}
		})
				 
computed:{
		...mapState(["count","num","apple"]),
		hw(){
				return "hello world!"
			}
}

Note: / / it cannot be modified directly (the page value can change, but the warehouse value remains unchanged). The modification is handled by the warehouse administrator
this.$store.state.count++;

//Handle ---- "changes" through the warehouse administrator

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // Change status
      state.count++
    }
  }
})

Store. Needs to be called with the corresponding type Commit method:

store.commit('increment')

Getter is similar to calculating properties in Vue

Similar to the calculation attribute in Vue (it can be considered as the calculation attribute of Store, which processes the data in the Store to form new data), the return value of getter will be cached according to its dependency, and will be recalculated only when its dependency value changes.

The Getter method accepts state as its first parameter:

1. Use
{{this.$store.getters.donearr}} don't use it without cache

2.computed

computed:{//Role of cache
	donearr(){
			return this.$store.getters.donearr
	}
}

3.mapGetters auxiliary function

import { mapGetters } from 'vuex'
 
computed: {
    ...mapGetters(['donearr'])
}

Mutations is similar to methods synchronization in vue

Why can't you use direct asynchrony in Mutation

Mutation is used to change the data in the Store.

The data in the Store can only be changed through a mutation. You can't directly operate the data in the Store. You can modify it by commit ting a mutation. Its essence is actually a function

In this way, although the operation is a little cumbersome, it can centrally monitor the changes of all data
The mutation operation must be synchronized

Every time we submit a mutation, we will have a record. Vuex does this to make it easier to record the history and track of each data change, and to facilitate operations such as listening and rollback

1. Use the mutation defined in js to call through commit

mutations:{
		addcount(state,payload){
		   state.count+=payload;//Change status
		   }
},
// Trigger mutation in component
changecount(){
	//It is handled by the warehouse administrator
  // The first way to trigger changes
this.$store.commit("addcount",{n:100,m:1000});}

2. Pass parameters when triggering changes:

// store.js
mutations: {
    addN(state, step) {  //The first parameter is state, and the following parameter is store The additional parameter passed in by commit, that is, the payload of mutation
        state.count += step
    }
}
 
// In component
this.$store.commit('addN', 3) // When the commit function is called, the commit parameter is carried

3.mapMutations auxiliary function

// 1. Import mapMutations function from vuex as needed
import { mapMutations } from 'vuex'
 
// 2. Map the specified changes function to the methods function of the current component through the mapchanges function just imported
methods: {
    ...mapMutations(['add', 'addN'])
}

Actions is similar to methods asynchronous in vue

● the Action submits the Mutation instead of directly changing the status. (through Mutation)

● Action can contain any asynchronous operation.

vueX: Note: context --- {commit dispatch, state...}

Note: do not perform asynchronous operations in the mutations function, such as adding a delayer

Only the functions defined in changes have the right to modify the data in state; In actions, you cannot directly modify the data in state. You must use context Commit triggers a mutation.

Context: context object, which is equivalent to this in the arrow function. It has the same properties and methods as the store instance

payload: mounted parameter

actions:{
		    	   addcountA(context,n){
		    		   console.log(context,n);
		    		   
		    		   setTimeout(function(){
		    		   		context.commit("addcount",n);
		    		   },1000)
		    	   }
		    }

1. Use dispatch

// store.js
const store = new Vuex.store({
    //... Omit other codes
    actions: {
        addAsync(context, payload) {
            setTimeout(() => {
                context.commit('add')
            }, 1000)
        }
    }
})

// Trigger Action in component
methods: {
    handle() {
        this.$store.dispatch('addAsync', 3)
    }
}

2. mapActions auxiliary function

<button @click="changecountA(5000)">modify countA</button>
			
import { mapState,mapActions} from 'vuex'
			
...mapActions({
	changecountA: 'addcountA' // Add ` this Changecounta() ` mapped to ` this$ store. dispatch('addcountA')`
})

Modules module

The store can be divided into modules. Each module has its own state, mutation, action, getter, and even nested sub modules

The function of named true is to tell vuex that all things in the module's state, getters, variations and actions need to be added with a namespace when calling. This namespace is the name of the module when it is improved.

//ModuleA.js
const moduleA = {
	namespaced: "true",
	state: {
		msg: "moduleA...",
		name: "lili",
		age: 28
	}
}
export default moduleA;

1. Use

this.$store.state.a.msg;

2.computed

msg() {
      return this.$store.state.a.msg;
 }

3. Usage of auxiliary functions: 3

  • 3.1 arrow function
import { mapState } from "vuex";

...mapState({
   msg: (state) => state.a.msg,
   name: (state) => state.a.name,
   age: (state) => state.a.age,
})
  • 3.2 array form
import { mapState } from "vuex";

...mapState("a",["msg","name","age"])
  • 3.3 through auxiliary functions

You can create helper functions based on a namespace by using createNamespacedHelpers. It returns an object with a new component binding auxiliary function bound to the given namespace value:

import { createNamespacedHelpers } from 'vuex'
const { mapState } = createNamespacedHelpers('a')

...mapState(["msg","name","age"])

4, Function

It can easily realize the data sharing between components

Benefits of using Vuex to uniformly manage state:

● it can centrally manage the shared data in Vuex, which is easy to develop and maintain later

● it can efficiently realize data sharing between components and improve development efficiency

● the data stored in Vuex is responsive and can keep the data synchronized with the page in real time

What kind of data is suitable for storage in Vuex

Generally, only the data shared between components is necessary to be stored in Vuex; The private data of the component can still be stored in the data of the component itself.

  • Multiple views depend on the same state: for example, data sharing among multiple components can get user information on different pages

  • Behaviors from different views need to change the same state: for example, user member information can be changed on different pages

Topics: Vue