Understanding Vuex

What is Vuex

A Vue plug- in that specifically implements centralized state (data) management in Vue. It performs centralized management (read/write) on the shared state of multiple components in Vue applications . It is also a way of communication between components, and is suitable for Communication between arbitrary components

Vuex Github address 

When to use Vuex

Multiple components rely on the same data, and behaviors from different components need to change the same data

Working principle diagram

We are using vue2, so the command to install vuex is: npm i vuex@3

Reason: The following code will be executed after the imported things are executed first. The solution: use Vue.use(Vuex) under store/index.js 

Written in pure Vue

src/App.vue

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

<script>
import Count from './components/Count'
export default {
    name: 'App',
    components: { Count },

}
</script>

src/components/Count.vue

<template>
  <div>
    <h1>当前求和为:{
   
   { sum }}</h1>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementOdd">当前求和为奇数再加</button>
    <button @click="incrementWait">等一等再加</button>
  </div>
</template>

<script>
export default {
  name: 'Count',
  data(){
    return{
      sum:0,  //当前的和
      n:1     //用户选择的数字
    }
  },
  methods:{
    increment(){
      this.sum+=this.n
    },
    decrement(){
      this.sum-=this.n
    },
    incrementOdd(){
      if(this.sum%2)
        this.sum+=this.n
    },
    incrementWait(){
      setTimeout(()=>{
        this.sum+=this.n
      },500)
    }
  }
}
</script>

<style>
  button{
    margin-left: 5px;
  }
</style>

Build the Vuex environment

Create src/store/index.js This file is used to create the most core store in Vuex

//引入vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// actions对象:用于响应组件中的动作
const actions={
    // context相当于精简版的$store
    jiaOdd(context,value){
        console.log('actions中的jiaOdd被调用了');
        if(context.state.sum%2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了');
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    }
}
// mutations对象:用于操作数据(state)
const mutations={
    JIA(state,value){
        console.log('mutations中的JIA被调用了');
        state.sum+=value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了');
        state.sum-=value
    }
}
// state对象:用于存储数据
const state={
    sum:0   //当前的和
}
// 暴露/导出store
export default new Vuex.Store({
    actions,
    mutations,
    state
})

Pass in the store configuration item when creating a vm in src /main.js

import Vue from 'vue'
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'

import store from './store'
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)

//创建vm
new Vue({
    el: '#app',
    render: h => h(App),
    store,
    beforeCreate(){
        Vue.prototype.$bus=this //安装全局事件总线
    }
})

Basic use of Vuex

Memory method: After customers enter the restaurant, if they are not familiar with the dishes, they need to ask the waiter to recommend them. If they come often, then skip the waiter and talk to the chef directly. Dispatch is equivalent to the waiter, and commit is equivalent to the back chef. Kitchen, state is equivalent to dishes 

src/components/Count.vue 

<template>
  <div>
    <h1>当前求和为:{
   
   { $store.state.sum }}</h1>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementOdd">当前求和为奇数再加</button>
    <button @click="incrementWait">等一等再加</button>
  </div>
</template>

<script>
export default {
  name: 'Count',
  data(){
    return{
      n:1     //用户选择的数字
    }
  },
  methods:{
    increment(){
      this.$store.commit('JIA',this.n)
    },
    decrement(){
      this.$store.commit('JIAN',this.n)
    },
    incrementOdd(){
      this.$store.dispatch('jiaOdd',this.n)
    },
    incrementWait(){
      this.$store.dispatch('jiaWait',this.n)
    }
  }
}
</script>

<style>
  button{
    margin-left: 5px;
  }
</style>

getters configuration item

src/store/index.js

//引入vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// actions对象:用于响应组件中的动作
const actions={
    // context相当于精简版的$store
    jiaOdd(context,value){
        console.log('actions中的jiaOdd被调用了');
        if(context.state.sum%2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了');
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    }
}
// mutations对象:用于操作数据(state)
const mutations={
    JIA(state,value){
        console.log('mutations中的JIA被调用了');
        state.sum+=value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了');
        state.sum-=value
    }
}
// state对象:用于存储数据
const state={
    sum:0,   //当前的和
    school:'黑马',
    subject:'前端'
}
//
const getters={
    bigSum(state){
        return state.sum*10
    }
}
// 暴露/导出store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

The use of four map methods

Only when the mapping data name and the data name from the state are the same can be written in an array

1.mapState method: used to help map the data in the State as a computed property

2.mapGetters method: used to help map the data in getters to computed properties

3.mapMutations method: a method used to help generate conversations with mutations

4.mapActions method: a method used to help generate dialogs with actions

<template>
  <div>
    <h1>当前求和为:{
   
   { sum }}</h1>
    <h1>当前求和放大10倍为:{
   
   { bigSum }}</h1>
    <h1>我在{
   
   { school }},学习{
   
   { subject }}</h1>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementOdd(n)">当前求和为奇数再加</button>
    <button @click="incrementWait(n)">等一等再加</button>
  </div>
</template>

<script>
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
export default {
  name: 'Count',
  data() {
    return {
      n: 1     //用户选择的数字
    }
  },
  computed:{
    // 对象写法1
    // ...mapState({sum:'sum',school:'school',subject:'subject'}),
    // 数组写法2
    ...mapState(['sum','school','subject']),
    // 值必须加单引号,如果没有加的话,会变成寻找变量
    // ...mapGetters({bigSum:'bigSum'})
    ...mapGetters(['bigSum'])
  },
  methods: {
    /* increment() {
      this.$store.commit('JIA', this.n)
    },
    decrement() {
      this.$store.commit('JIAN', this.n)
    },
    incrementOdd() {
      this.$store.dispatch('jiaOdd', this.n)
    },
    incrementWait() {
      this.$store.dispatch('jiaWait', this.n)
    } */

    ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    // ...mapMutations(['JIA','JIAN']),

    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    // ...mapActions('jiaOdd','jiaWait')
  }
}
</script>

<style>
button {
  margin-left: 5px;
}
</style>

Note: When using mapActions and mapMutations, if you need to pass parameters, you need to pass the parameters when binding the event in the template, otherwise the parameter is the event object event

Multi-component shared data case

src/components/Count.vue

<template>
  <div>
    <h1>当前求和为:{
   
   { sum }}</h1>
    <h4 style="color:red">Person组件总人数为:{
   
   { personList.length }}</h4>
    <h1>当前求和放大10倍为:{
   
   { bigSum }}</h1>
    <h1>我在{
   
   { school }},学习{
   
   { subject }}</h1>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementOdd(n)">当前求和为奇数再加</button>
    <button @click="incrementWait(n)">等一等再加</button>
  </div>
</template>

<script>
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
export default {
  name: 'Count',
  data() {
    return {
      n: 1     //用户选择的数字
    }
  },
  computed:{
    ...mapState(['sum','school','subject','personList']),
    ...mapGetters(['bigSum'])
  },
  methods: {
    ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
  }
}
</script>

<style>
button {
  margin-left: 5px;
}
</style>

src/components/Person.vue

<template>
  <div>
    <h1>人员列表</h1>
    <h4 style="color: red;">Count组件求和为:{
   
   { sum }}</h4>
    <input type="text" placeholder="请输入名字" v-model="name">
    <button @click="add">添加</button>
    <ul>
      <li v-for="p in personList" :key="p.id">{
   
   { p.name }}</li>
    </ul>
  </div>
</template>

<script>
import { nanoid } from 'nanoid'
export default {
  name: 'Person',
  data() {
    return {
      name: ''
    }
  },
  computed: {
    personList() {
      return this.$store.state.personList
    },
    sum() {
      return this.$store.state.sum
    }
  },
  methods: {
    add() {
      if (this.name === '') return
      const personObj = { id: nanoid(), name: this.name }
      // console.log(personObj)
      this.$store.commit('ADD_PERSON', personObj)
      this.name = ''
    }
  }
}
</script>

src/App.vue

<template>
    <div>
        <Count/>
        <hr>
        <Person/>
    </div>
</template>

<script>
import Count from './components/Count'
import Person from './components/Person'
export default {
    name: 'App',
    components: { Count,Person },

}
</script>

src/store/index.js

//引入vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// actions对象:用于响应组件中的动作
const actions={
    // context相当于精简版的$store
    jiaOdd(context,value){
        console.log('actions中的jiaOdd被调用了');
        if(context.state.sum%2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了');
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    }
}
// mutations对象:用于操作数据(state)
const mutations={
    JIA(state,value){
        console.log('mutations中的JIA被调用了');
        state.sum+=value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了');
        state.sum-=value
    },
    ADD_PERSON(state,value){
        console.log('mutations中的JIAN被调用了');
        state.personList.unshift(value)
    }
}
// state对象:用于存储数据
const state={
    sum:0,   //当前的和
    school:'黑马',
    subject:'前端',
    personList:[
        {id:'001',name:'张三'}
    ]
}
//
const getters={
    bigSum(state){
        return state.sum*10
    }
}
// 暴露/导出store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

src/main.js

import Vue from 'vue'
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'

import store from './store'
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)

//创建vm
new Vue({
    el: '#app',
    render: h => h(App),
    store,
    beforeCreate(){
        Vue.prototype.$bus=this //安装全局事件总线
    }
})

 

Guess you like

Origin blog.csdn.net/bubbleJessica/article/details/131704893