catalogue
3, Use of four map methods ----------- multi component shared data
1, Concept
What is vuex: a Vue plug-in dedicated to centralized state (data) management in Vue, which centrally manages (read / write) the shared state of multiple components in Vue applications. It is also a way of communication between components, and is suitable for communication between any components
When to use Vuex:
- Multiple components depend on the same state
- Behaviors from different components need to change the same state
- Generally speaking, it is shared
2, Use steps
Step 1: install vuex
npm i vuex
Step 2: create a store folder and create a new index JS file, which is used to create the most core store in vuex
//Introduce vue import Vue from 'vue' // Introduce Vuex import Vuex from "vuex" // Using Vuex Vue.use(Vuex) //Prepare actions -- for the actions in the responsive component, and the business logic is written here const actions = {....} //Prepare mutation -- for operation data (state) can only be operations const mutations = {....} //Prepare state -- for storing data const state ={....} //Prepare getters -- used to process the data in state const getters = {....} //Create and expose the store export default new Vuex.Store({ actions, mutations, state, getters })
Step 3: pass in the store configuration item in the entry function
import Vue from "vue"; import App from './App.vue' // Introducing store import store from './store/index' Vue.config.productionTip = false //Create vue new Vue({ el: '#app', render: h => h(App), store: store, //It can be abbreviated as store })
Read the data in vuex from components: [the same is true for multi component data sharing. You can get the data through the following methods]
$store.state.xx
$store.getters.xx
Modify vuex data in the component:
Method 1: $store Dispatch ('method name in action ', data)
Method 2: $store Commit ('method name in changes', data) Note: the method name needs to be larger
3, Use of four map methods ----------- multi component shared data
Import from component:
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
⚠️ Note: the following array writing conditions are: when the calculated attribute is the same as the read data name, an attribute has two usages
3.1 mapState method
Function: it is used to help us map the data in state into calculation attributes
Object writing:
...mapState({he:'sum',xuexiao:'school',xueke:'subject'})
Array writing:
...mapState(['sum','school','subject'])
3.2 mapGetters method
Function: it is used to help us map the data in getters into calculated attributes
Object writing:
...mapGetters({bigSum:'bigSum'})
Array writing:
...mapGetters(['bigSum'])
⚠️ Note: the following array writing conditions are: when the method name is the same as the submitted method name, a method has two usages
3.3 mapMutations method
Function: the method used to help us generate a conversation with movements, which is written in $store The function of dispatch (xxx) is written in methods. In the method, commit will be called to contact changes
Object writing method: < button @ Click = "increase (n)" > + < / button > click the event function to carry parameters
...mapMutations({ increament:'JIA',decreament:'JIAN'})
Array writing:
...mapMutations(['JIA','JIAN'])
3.4 mapActions method
Function: the method used to help us generate a dialogue with actions, namely $store The function of dispatch (xxx) will call dispatch in the method to contact actions
Object method:
...mapActions({inceamentOdd:'jiaOdd',increamentWait:'Waitjia'})
Array writing:
...mapActions(['jiaOdd','Waitjia'])
4, Modular plus namespace
Purpose: to make the code easier to maintain and make the classification of multiple data more clear
Namespace
Introduce namespace to solve the problem of name conflict in different modules
After setting named: true, the module will find the method in its own module no matter what operation it performs. The product/setName event is submitted in the commit, and the setName event during export just becomes product/setName. This is a perfect way to throw the event in this module and will not affect other modules
See the example:
store/index.js
Import person. In the store file JS and count js
And configure: modules:{
countAbout:countOption,
personAbout:personOption,
}
// This file is used to create the most core store in vuex //Introduce vue import Vue from 'vue' // Introduce Vuex import Vuex from "vuex" // Using Vuex Vue.use(Vuex) import personOption from './person' import countOption from './count' //Create and expose the store export default new Vuex.Store({ modules: { countAbout: countOption, personAbout: personOption, } })
store/person.js
Personnel related configurations are written into this file
const personOption = {
Named: true, / / namespace
actions: {....}
mutations : {....}
state : {....}
getters : {....}
}
export default personOption
import axios from "axios"; import { nanoid } from "nanoid"; //Personnel management related configuration const personOption = { namespaced: true, actions: { addPersonWang(context, value) { console.log(1); if (value.name.indexOf('king') === 0) { context.commit('ADD_PERSON', value) } else { alert('Please enter a name that begins with Wang') } }, addPersonServer(context) { axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then( response => { context.commit('ADD_PERSON',{id:nanoid(),name:response.data}) }, error => { alert(error.massage) } ) } }, mutations: { ADD_PERSON(state, value) { state.Person.unshift(value) } }, state: { Person: [ { id: '001', name: 'Zhang San' } ] }, getters: { firstName(state) { return state.Person[0].name } } } export default personOption
store/count.js
The configuration related to summation is written in this file
const countOption = {
Named: true, / / namespace
actions: {....}
mutations : {....}
state : {....}
getters : {....}
}
export default countOption
//Summation related configuration const countOption = { namespaced: true, actions: { jiaOdd(context, value) { if (context.state.sum % 2) { context.commit('JIA', value) } }, Waitjia(context, value) { setTimeout(() => { context.commit("JIA", value) }, 500); } }, mutations: { JIA(state, value) { state.sum += value }, JIAN(state, value) { state.sum -= value }, }, state: { sum: 0, //Current summation school: 'Shang Silicon Valley', subject: 'computer', }, getters: { bigSum(state) { return state.sum * 10 } } } export default countOption
Count.vue components:
Using the method provided by map:
...mapState('countAbout',['sum','school','subject'])
After the namespace is opened, / countAbout/sum is finally found
<template> <div> <h2>The result of summation is:{{ sum }}</h2> <h4>The result of the summation is magnified by 10 times:{{ bigSum }}</h4> <h5>I am here{{ school }},study{{ subject }}</h5> <h3 style="color: red">The total number of people below is:{{ Person.length }}</h3> <select v-model.number="n"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button @click="increament(n)">+</button> <button @click="decrement(n)">-</button> <button @click="increamentOdd(n)">The current sum is odd plus</button> <button @click="increamentWait(n)">Wait a minute</button> </div> </template> <script> import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; export default { name: "Count", data() { return { n: 1, //User selected number }; }, computed: { ...mapState("countAbout", ["sum", "school", "subject"]), ...mapState("personAbout", ["Person"]), ...mapGetters("countAbout", ["bigSum"]), }, methods: { ...mapMutations("countAbout", { increament: "JIA", decrement: "JIAN" }), ...mapActions("countAbout", { increamentOdd: "jiaOdd", increamentWait: "Waitjia", }), }, } </script>
Person.vue component
Write your own calculation attributes: pay attention to the difference between the two
this.$store.state.personAbout.Person
this.$store.getters['personAbout/firstName']
Write your own method
this.$store.commit("personAbout/ADD_PERSON", personObj);
<template> <div> <h3>Personnel list</h3> <h3>The first person's name is:{{ firstName }}</h3> <input type="text" v-model="name" /> <button @click="add">add to</button> <button @click="addWang">Add a person surnamed Wang</button> <button @click="addPersonServer">Add a person's name randomly</button> <ul> <li v-for="p in Person" :key="p.id">{{ p.name }}</li> </ul> <h3 style="color: red">Upper component sum by:{{ sum }}</h3> </div> </template> <script> import { nanoid } from "nanoid"; export default { name: "Person", data() { return { name: "", }; }, computed: { Person() { return this.$store.state.personAbout.Person; }, sum() { return this.$store.state.countAbout.sum; }, firstName() { return this.$store.getters["personAbout/firstName"]; }, }, methods: { add() { const personObj = { id: nanoid(), name: this.name }; this.$store.commit("personAbout/ADD_PERSON", personObj); this.name = ""; }, addWang() { const personObj = { id: nanoid(), name: this.name }; this.$store.dispatch("personAbout/addPersonWang", personObj); this.name = ""; }, addPersonServer() { //Because it is a randomly added personal name, all do not need to bring data, but the data obtained by the request server this.$store.dispatch('personAbout/addPersonServer') }, }, } </script>