vuex原理图

vue2中,使用vuex3版本

vue3中,使用vuex4版本

yarn add vuex安装之后,切记重启yarn serve服务

实验小插曲

在后面一次回忆复习的时候,因为版本问题导致Vuex无法注册成功,排查了半个小时。最后发现是安装Vuex安装错了版本。使用的是Vue2,正确安装Vuex的命令应该是yarn add vuex@3,但是直接yarn add vuex命令安装,导致控制台输出vm实例中一直没有.$store属性

import Vuex,{ Store } from "vuex";
import Vue from 'vue';

// 在vue中注册vuex插件
Vue.use(Vuex);
// 用于响应组件的动作
const actions={};

// 用于操作数据
const mutations={};

// 用于存储数据
const state={
    //
};

// 用于数据的加工
const getters={

};

export default new Store({
    actions,
    mutations,
    state,
    getters
});

Vue2五大核心

  • state

    用于管理数据状态

    mapState 用于遍历state的状态

    //模拟数据
    // @/store/index.js
    const state={
        schoolName:'黄冈师范学院',
        age:100,
        type:'师范'
    };
    
    // @/component/Index.vue
    const computed={
        ...mapState(["schoolName", "age", "type"]), //数组写法
        ...mapState({
          //对象写法
          schoolName: "schoolName",
          age: (state) => state.age,
          type(state) {
            return "_" + state.type + "_";
          },
        })
    }

    image-20221027132041292

  • getters

    加工state状态

    mapGetters

    //模拟数据
    // @/store/index.js
    const state={
        schoolName:'黄冈师范学院',
        age:100,
        type:'师范'
    };
    
    // @/component/Index.vue
    const computed={
        ...mapGetters(['bigAge','desc']),
        ...mapGetters({
            bigAge:'bigAge',
            desc:'desc'
        })
        //特别指出,mapGetters方法不允许写函数形式
    }
  • mutation

    更改state状态的唯一方法

    不要进行异步操作,就进行简单的状态更新操作

    调用

    • store.commit('XXX',{payload}) payload[载荷]

    • store.commit({
          type:'XXX',
          ...payload
      })

    注册

    const mutations = {
        increment(state, n) {
            state.count += n
        }
    }

    mapMutations

    //模拟数据
    // @/store/index.js
    const mutations={
        ADDAGE(state,payload){
            console.log('mutations-ADDAGE',state,payload);
            state.age+=payload.age;
        }
    };
    
    // @/component/Index.vue
    const methods = {
        ...mapMutations({
            add: 'ADDAGE'
        }),
        ...mapMutations(['ADDAGE'])
    }
    
    //<button @click="add({age:2})">年龄+2(mapMutations映射方式)</button>
    //<button @click="ADDAGE({age:2})">年龄+3(mapMutations映射方式)</button>
  • action

    调用mutation改变state状态,而不是直接改变

    可以进行异步操作

    注册

    //模拟数据
    // @/store/index.js
    const actions={
        addOne(context){
            context.commit('ADDNUM',{val:1});
        },
        addOne2({commit}){
            commit({
                type:'ADDNUM',
                val:1
            });
        }
    }
    
    // @/component/Index.vue
    const methods={
        addOne(){
            this.$store.dispatch('addOne');
        },
        addOne2(){
            this.$store.dispatch({
                type:'addOne2'
            })
        }
    }
    
    //<button @click="addOne">数字+1</button>
    //<button @click="addOne2">数字+1(方式2)</button>

    调用

    this.$store.diapathc('xxx',{...payload})
    this.$store.diapathc({
        type:'xxx',
        ...payload
    })

    mapActions

    const methods={
        ...mapActions(['addOne']),
        ...mapActions({
            addOne:'addOne'
        })
    }
  • modules

    所有状态放在一个状态对象之下,对象会比较大,Vuex允许分割成模块,每个模块拥有自己的stateactionmutationgetter

练习1

~/components/Count.vue

<template>
  <div>
    <h4>total:{{ $store.state.sum }}</h4>
    <h4>big10 total:{{ $store.getters.bigSum }}</h4>
    <select v-model.number="abc">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="addNum">指定+</button>
    <button @click="addOne">+1</button>
    <button @click="addOdd">奇数+1</button>
    <button @click="addWait">延迟+1</button>
  </div>
</template>

<script>
export default {
  name: "Count",
  data() {
    return {
      sum: 0,
      abc: 1,
    };
  },
  methods: {
    addNum() {
      //   this.sum += this.abc;
      this.$store.commit("addNum", this.abc);
    },
    addOne() {
      //   this.sum++;
      this.$store.dispatch("addOne", this.abc);
    },
    addOdd() {
      //   if (this.sum % 2) {
      //     this.sum++;
      //   }
      this.$store.dispatch("addOdd", this.abc);
    },
    addWait() {
      //   setTimeout(() => {
      //     this.sum++;
      //   }, 500);
      this.$store.dispatch("addWait", this.abc);
    },
  },
};
</script>

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

~/store/index.js

import Vuex, { Store } from "vuex";
import Vue from 'vue';

Vue.use(Vuex);
// 用于响应组件的动作
const actions = {
    addNum(context, value) {
        console.log(context, value);
        context.commit('addNum', value);
    },
    addOne(context) {
        context.commit('addNum', 1);
    },
    addOdd(context) {
        if (context.state.sum % 2) {
            context.commit('addNum', 1);
        }
    },
    addWait(context) {
        setTimeout(() => {
            context.commit('addNum', 1);
        }, 500);
    }
};

// 用于操作数据
const mutations = {
    addNum(state, value) {
        // console.log('mutations addNum',state,value);
        state.sum += value;
    }
};

// 用于存储数据
const state = {
    sum: 0
};

const getters = {
    bigSum(state) {
        return state.sum * 10;
    }
};

export default new Store({
    actions,
    mutations,
    state,
    getters
});

image-20221027124543816