• 12-Vue技术栈之Vuex的使用


    1、理解 vuex

    1.1 vuex 是什么

    1. 概念:专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信
    2. Github 地址: https://github.com/vuejs/vuex

    1.2 什么时候使用 Vue

    1. 多个组件依赖于同一状态
    2. 来自不同组件的行为需要变更同一状态

    简单来说就是多个组件需要共享数据时

    1.3 图解两种方式实现数据共享

    • 使用全局事件总线实现多组件共享数据较为麻烦。

    请添加图片描述

    • 使用Vuex实现多组件共享数据简便。

    请添加图片描述

    2、搭建vuex环境

    2.1 下载vuex

    npm i vuex
    
    • 1

    在这里插入图片描述

    注:
    如果执行npm i vuex默认安装的是vuex4版本,而vuex4版本只能在vue3里面使用,所以如果你用的是vue2需要指定安装vuex3的版本。

    vue2里正确安装:

    npm i vuex@3
    
    • 1

    2.2 配置文件

    1. 创建文件:src/store/index.js
    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //应用Vuex插件
    Vue.use(Vuex)
    
    //准备actions对象——响应组件中用户的动作
    const actions = {}
    //准备mutations对象——修改state中的数据
    const mutations = {}
    //准备state对象——保存具体的数据
    const state = {}
    
    //创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. main.js中创建vm时传入store配置项
    ......
    //引入Vue
    import Vue from 'vue'
    //引入App
    import App from './App.vue'
    //引入store
    import store from './store/index.js'
    ......
    
    //创建vm
    new Vue({
    	el:'#app',
    	render: h => h(App),
    	store
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3、基本使用

    • vuex工作原理图:

    在这里插入图片描述

    1. 初始化数据、配置actions、配置mutations,操作文件store.js
    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //引用Vuex
    Vue.use(Vuex)
    
    const actions = {
        //响应组件中加的动作
    	jia(context,value){
    		// console.log('actions中的jia被调用了',miniStore,value)
    		context.commit('JIA',value)
    	},
    }
    
    const mutations = {
        //执行加
    	JIA(state,value){
    		// console.log('mutations中的JIA被调用了',state,value)
    		state.sum += value
    	}
    }
    
    //初始化数据
    const state = {
       sum:0
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state,
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    1. 组件中读取vuex中的数据:$store.state.sum

    2. 组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)$store.commit('mutations中的方法名',数据)

      备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

    3.1 求和案例纯vue写法

    • 我们来用纯Vue写一个案例,在用vuex重新书写一遍,形成一个对比。

    实现效果:

    请添加图片描述
    结构目录:
    在这里插入图片描述

    代码示例:
    main 文件

    import Vue from 'vue'
    import App from './App.vue'
    Vue.config.productionTip = false
     new Vue({
      render: h => h(App),
    }).$mount('#app')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    App组件

    <template>
      <Count/>
    template>
    
    <script>
    import Count from './components/Count'
    export default {
      name:'App',
      components:{Count}
    }
    script>
    
    <style>
    
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Count组件

    <template>
      <div>
        <h1>当前求和为:{{ sum }}h1>
        <select v-model.number="n">
          <option value="1">1option>
          <option value="2">2option>
          <option value="3">3option>
        select>
        <button @click="add">+button>
        <button @click="subtract">-button>
        <button @click="addOdd">当前和为奇数再加button>
        <button @click="addWait">等一等再加button>
      div>
    template>
    
    <script>
    export default {
      name: "Count",
      data() {
        return {
          n: 1, //选择数
          sum: 0, //求和数
        };
      },
      methods: {
        add() {
          this.sum += this.n;
        },
        subtract() {
          this.sum -= this.n;
        },
        addOdd() {
          if (this.sum % 2) {
            this.sum += this.n;
          }
        },
        addWait() {
          setTimeout(() => {
            this.sum += this.n;
          }, 500);
        },
      },
    };
    script>
    
    <style>
    h1 {
      color: pink;
    }
    select {
      width: 50px;
      background: pink;
    }
    button {
      margin: 5px;
      padding: 5px 10px;
      background: pink;
      border: none;
      cursor: pointer;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    3.2 求和案例vuex写法

    实现效果:

    请添加图片描述
    结构目录:

    在这里插入图片描述
    main文件

    import Vue from 'vue'
    import App from './App.vue'
    //引入store里面的index.js文件,vue里默认引入的就是index文件
    import store from './store'
    Vue.config.productionTip = false
    const vm = new Vue({
      render: h => h(App),
      store //安装store
    }).$mount('#app')
    console.log(vm);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    App组件

    <template>
      <Count/>
    template>
    
    <script>
    import Count from './components/Count'
    export default {
      name:'App',
      components:{Count}
    }
    script>
    <style>
    
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Count组件

    <template>
      <div>
        <h1>当前求和为:{{ $store.state.sum }}h1>
        <select v-model.number="n">
          <option value="1">1option>
          <option value="2">2option>
          <option value="3">3option>
        select>
        <button @click="add">+button>
        <button @click="subtract">-button>
        <button @click="addOdd">当前和为奇数再加button>
        <button @click="addWait">等一等再加button>
      div>
    template>
    
    <script>
    export default {
      name: "Count",
      data() {
        return {
          n: 1, //选择数
        };
      },
      methods: {
        add() {
          this.$store.commit("ADD", this.n);
        },
        subtract() {
          this.$store.commit("SUBTRACT", this.n);
        },
        addOdd() {
          this.$store.dispatch("addOdd", this.n);
        },
        addWait() {
          this.$store.dispatch("addWait", this.n);
        },
      },
    };
    script>
    
    <style>
    h1 {
      color: pink;
    }
    select {
      width: 50px;
      background: pink;
    }
    button {
      margin: 5px;
      padding: 5px 10px;
      background: pink;
      border: none;
      cursor: pointer;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    store里面的index.js 文件

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //应用Vuex插件
    Vue.use(Vuex)
    
    //准备actions对象——响应组件中用户的动作
    const actions = {
    	addOdd(context, value) {
    		if (context.state.sum % 2) {
    			context.commit('ADD', value)
    		};
    	},
    	addWait(context, value) {
    		setTimeout(() => {
    			context.commit('ADD', value)
    		}, 500);
    	}
    }
    //准备mutations对象——修改state中的数据
    const mutations = {
    	ADD(context, value) {
    		context.sum += value
    	},
    	SUBTRACT(context, value) {
    		context.sum -= value
    	},
    
    }
    //准备state对象——保存具体的数据
    const state = {
    	sum: 0, //求和数
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    4、getters的使用

    1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。

    2. store.js中追加getters配置

      ......
      
      const getters = {
      	bigSum(state){
      		return state.sum * 10
      		//靠返回值
      	}
      }
      
      //创建并暴露store
      export default new Vuex.Store({
      	......
      	getters
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    3. 组件中读取数据:$store.getters.bigSum

    5、四个map方法的使用

    1. mapState方法:用于帮助我们映射state中的数据为计算属性
    computed: {
        //借助mapState生成计算属性:sum、school、subject(对象写法)
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum','school','subject']),
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. mapGetters方法:用于帮助我们映射getters中的数据为计算属性
    computed: {
        //借助mapGetters生成计算属性:bigSum(对象写法)
        ...mapGetters({bigSum:'bigSum'}),
    
        //借助mapGetters生成计算属性:bigSum(数组写法)
        ...mapGetters(['bigSum'])
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数
    methods:{
        //靠mapActions生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
        //靠mapActions生成:incrementOdd、incrementWait(数组形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数
    methods:{
        //靠mapActions生成:increment、decrement(对象形式)
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
        
        //靠mapMutations生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    备注:在四个方法使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

    5.1 求和案例

    • 我们将上面的求和案例利用这些方法进行改进一下:
    • 其他文件照常,只改变store里面的index.jsCount组件
      index.js文件
    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //应用Vuex插件
    Vue.use(Vuex)
    
    //准备actions对象——响应组件中用户的动作
    const actions = {
    	/* add(context, value) {
    		context.commit('ADD', value)
    	},
    	subtract(context, value) {
    		context.commit('SUBTRACT', value)
    	}, */
    	addOdd(context, value) {
    		if (context.state.sum % 2) {
    			context.commit('ADD', value)
    		};
    	},
    	addWait(context, value) {
    		setTimeout(() => {
    			context.commit('ADD', value)
    		}, 500);
    	}
    }
    //准备mutations对象——修改state中的数据
    const mutations = {
    	ADD(context, value) {
    		context.sum += value
    	},
    	SUBTRACT(context, value) {
    		context.sum -= value
    	},
    
    }
    //准备state对象——保存具体的数据
    const state = {
    	sum: 0, //求和数
    	school:'哔站',
    	subject:'前端'
    }
    // 对state对象里的数据进行加工
    const getters = {
    	bigSum(state) {
    		return state.sum * 10
    	}
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state,
    	getters
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    Count组件

    <template>
      <div>
        <h1>当前求和为:{{ sum }}h1>
        <h3>放大十倍后的和为:{{ bigSum }}h3>
        <h3>我在{{ school }}学{{ subject }}h3>
    
        <select v-model.number="n">
          <option value="1">1option>
          <option value="2">2option>
          <option value="3">3option>
        select>
        <button @click="add(n)">+button>
        <button @click="subtract(n)">-button>
        <button @click="addOdd(n)">当前和为奇数再加button>
        <button @click="addWait(n)">等一等再加button>
      div>
    template>
    
    <script>
    // 导入4个map方法
    import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
    export default {
      name: "Count",
      data() {
        return {
          n: 1, //选择数
        };
      },
      computed: {
        //靠程序员自己亲自去写计算属性
        /* sum(){
    				return this.$store.state.sum
    			},
    			school(){
    				return this.$store.state.school
    			},
    			subject(){
    				return this.$store.state.subject
    			}, */
    
        //借助mapState生成计算属性,从state中读取数据。(对象写法)
        // ...mapState({ sum: "sum", school: "school", subject: "subject" }),
        //借助mapState生成计算属性,从state中读取数据。(数组写法)
        // 数组写法必须数据名和计算方法名一致
        ...mapState(["sum", "school", "subject"]),
        // ...............................
        //靠程序员自己亲自去写计算属性
        /* bigSum(){
    				return this.$store.getters.bigSum
    			}, */
        //借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
        // ...mapGetters({bigSum:'bigSum'})
        //借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
        ...mapGetters(["bigSum"]),
      },
      methods: {
        //程序员亲自写方法
        /*   add() {
          this.$store.commit("ADD", this.n);
        },
        subtract() {
          this.$store.commit("SUBTRACT", this.n);
        },
        addOdd() {
          this.$store.dispatch("addOdd", this.n);
        },
        addWait() {
          this.$store.dispatch("addWait", this.n);
        }, */
    
        //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
        ...mapMutations({ add: "ADD", subtract: "SUBTRACT" }), //必须在插值语法中传入实参,不然默认是event事件对象
        //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)数组写法必须数据名和方法名一致,这里改了,上面调用的时候也要改。
        // ...mapMutations({ADD:'ADD',SUBTRACT:'SUBTRACT'})
    
        //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
        // ...mapActions({addOdd:'addOdd',addWait:'addWait'})
        //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
        ...mapActions(["addOdd", "addWait"]),
      },
    };
    script>
    
    <style>
    h1,
    h3 {
      color: pink;
    }
    select {
      width: 50px;
      background: pink;
    }
    button {
      margin: 5px;
      padding: 5px 10px;
      background: pink;
      border: none;
      cursor: pointer;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    6、 模块化+命名空间

    • 目的:让代码更好维护,让多种数据分类更加明确。

    • 修改store.js

      const countAbout = {
        namespaced:true,//开启命名空间
        state:{x:1},
        mutations: { ... },
        actions: { ... },
        getters: {
          bigSum(state){
             return state.sum * 10
          }
        }
      }
      
      const personAbout = {
        namespaced:true,//开启命名空间
        state:{ ... },
        mutations: { ... },
        actions: { ... }
      }
      
      const store = new Vuex.Store({
        modules: {
          countAbout,
          personAbout
        }
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
    • 开启命名空间后,组件中读取state数据:

      //方式一:自己直接读取
      this.$store.state.personAbout.list
      //方式二:借助mapState读取:
      ...mapState('countAbout',['sum','school','subject']),
      
      • 1
      • 2
      • 3
      • 4
    • 开启命名空间后,组件中读取getters数据:

      //方式一:自己直接读取
      this.$store.getters['personAbout/firstPersonName']
      //方式二:借助mapGetters读取:
      ...mapGetters('countAbout',['bigSum'])
      
      • 1
      • 2
      • 3
      • 4
    • 开启命名空间后,组件中调用dispatch

      //方式一:自己直接dispatch
      this.$store.dispatch('personAbout/addPersonWang',person)
      //方式二:借助mapActions:
      ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
      
      • 1
      • 2
      • 3
      • 4
    • 开启命名空间后,组件中调用commit

      //方式一:自己直接commit
      this.$store.commit('personAbout/ADD_PERSON',person)
      //方式二:借助mapMutations:
      ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
      
      • 1
      • 2
      • 3
      • 4

    6.1求和案例改造

    • 实现效果:

    请添加图片描述

    • 结构目录:

    在这里插入图片描述
    main文件

    import Vue from 'vue'
    import App from './App.vue'
    import store from './store'
    
    Vue.config.productionTip = false
    
     new Vue({
      render: h => h(App),
      store
    }).$mount('#app')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    App组件

    <template>
      <div>
        <Count />
        <Person />
      div>
    template>
    
    <script>
    import Count from "./components/Count";
    import Person from "./components/Person";
    export default {
      name: "App",
      components: { Count, Person },
    };
    script>
    <style>
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Count组件使用4种map方法

    <template>
      <div>
        <h1>当前求和为:{{ sum }}h1>
        <h3>放大十倍后的和为:{{ bigSum }}h3>
        <h3>我在{{ school }}学{{ subject }}h3>
        <h3 style="color: red">Person组件的总人数是:{{ persons.length }}h3>
        <select v-model.number="n">
          <option value="1">1option>
          <option value="2">2option>
          <option value="3">3option>
        select>
        <button @click="add(n)">+button>
        <button @click="subtract(n)">-button>
        <button @click="addOdd(n)">当前和为奇数再加button>
        <button @click="addWait(n)">等一等再加button>
      div>
    template>
    
    <script>
    // 导入4个map方法
    import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
    export default {
      name: "Count",
      data() {
        return {
          n: 1,
        };
      },
      computed: {
        //借助mapState生成计算属性,从state中读取数据。(数组写法)
        ...mapState('CountOptions',["sum", "school", "subject"]),
        ...mapState('PersonOptions',["persons"]),
        //借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
        ...mapGetters('CountOptions',["bigSum"]),
      },
      methods: {
        //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
        ...mapMutations('CountOptions',{ add: "ADD", subtract: "SUBTRACT" }),
        //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
        ...mapActions('CountOptions',["addOdd", "addWait"]),
      },
    };
    script>
    
    <style>
    h1,
    h3,
    li {
      color: pink;
    }
    select {
      width: 50px;
      background: pink;
    }
    button {
      margin: 5px;
      padding: 5px 10px;
      background: pink;
      border: none;
      cursor: pointer;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    Person组件不使用map方法,和上面的写法进行一个对比

    <template>
      <div>
        <h1>人员列表h1>
        <h3 style="color: red">Count组件求和为:{{ sum }}h3>
        <h3>列表中第一个人的名字是:{{ firstPersonName }}h3>
        <input type="text" placeholder="请输入名字" v-model="name" />
        <button @click="add">添加button>
        <button @click="addZhang">添加一个姓张的人button>
        <button @click="addPersonServer">随机添加一条语录button>
    
        <ul>
          <li v-for="p in persons" :key="p.id">{{ p.name }}li>
        ul>
      div>
    template>
    
    <script>
    import { nanoid } from "nanoid";
    export default {
      name: "Person",
      data() {
        return {
          name: "",
        };
      },
      computed: {
        persons() {
          //   return this.$store.state.persons
          return this.$store.state.PersonOptions.persons;
        },
        sum() {
          return this.$store.state.CountOptions.sum;
        },
        firstPersonName() {
          return this.$store.getters["PersonOptions/firstPersonName"];
        },
      },
      methods: {
        add() {
          const personObj = { id: nanoid(), name: this.name };
          this.$store.commit("PersonOptions/PersonAdd", personObj);
        },
        addZhang() {
          const personObj = { id: nanoid(), name: this.name };
          this.$store.dispatch("PersonOptions/addZhang", personObj);
        },
        addPersonServer() {
            this.$store.dispatch('PersonOptions/addPersonServer')
        }
      },
      mounted() {
        console.log(this.$store);
      },
    };
    script>
    
    <style>
    input::placeholder {
      color: pink;
    }
    input {
      border: 1px solid pink;
      padding: 5px;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    store/index.js文件

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    import axios from 'axios'
    import { nanoid } from 'nanoid'
    //应用Vuex插件
    Vue.use(Vuex)
    
    const CountOptions = {
    	namespaced: true,
    	actions: {
    		addOdd(context, value) {
    			if (context.state.sum % 2) {
    				context.commit('ADD', value)
    			};
    		},
    		addWait(context, value) {
    			setTimeout(() => {
    				context.commit('ADD', value)
    			}, 500);
    		}
    	},
    	mutations: {
    		ADD(state, value) {
    
    			state.sum += value
    		},
    		SUBTRACT(state, value) {
    			state.sum -= value
    		},
    	},
    	state: {
    		sum: 0, //求和数
    		school: '哔站',
    		subject: '前端',
    	},
    	getters: {
    		bigSum(state) {
    			return state.sum * 10
    		}
    	}
    }
    const PersonOptions = {
    	namespaced: true,
    	actions: {
    		addZhang(context, value) {
    			if (value.name.indexOf('张') === 0) {
    				context.commit('PersonAdd', value)
    			} else { alert('请输入姓张的人') }
    		},
    		addPersonServer(context) {
    			axios({
    				methods: 'get',
    				url: 'https://api.uixsj.cn/hitokoto/get?type=social'
    			}).then(response => {
    				context.commit('PersonAdd', { id: nanoid(), name: response.data })
    			}, error => { 
    				alert(error.message)
    			})
    		}
    	},
    	mutations: {
    		PersonAdd(state, value) {
    			state.persons.unshift(value)
    		}
    	},
    	state: {
    		persons: [{ id: "001", name: '张三' }]
    	},
    	getters: {
    		firstPersonName(state) {
    			return state.persons[0].name
    		}
    	}
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    	modules: {
    		CountOptions,
    		PersonOptions
    	}
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    store/index.js文件进行拆分

    • 目录结构
      在这里插入图片描述
      index.js
    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    
    
    import CountOptions from './CountOptions'
    import PersonOptions from './PersonOptions'
    //应用Vuex插件
    Vue.use(Vuex)
    
    //创建并暴露store
    export default new Vuex.Store({
    	modules: {
    		CountOptions,
    		PersonOptions
    	}
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    CountOptions.js

    export default {
    	namespaced: true,
    	actions: {
    		addOdd(context, value) {
    			if (context.state.sum % 2) {
    				context.commit('ADD', value)
    			};
    		},
    		addWait(context, value) {
    			setTimeout(() => {
    				context.commit('ADD', value)
    			}, 500);
    		}
    	},
    	mutations: {
    		ADD(state, value) {
    
    			state.sum += value
    		},
    		SUBTRACT(state, value) {
    			state.sum -= value
    		},
    	},
    	state: {
    		sum: 0, //求和数
    		school: '哔站',
    		subject: '前端',
    	},
    	getters: {
    		bigSum(state) {
    			return state.sum * 10
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    PersonOptions.js

    import axios from 'axios'
    import { nanoid } from 'nanoid'
    export default {
        namespaced: true,
        actions: {
            addZhang(context, value) {
                if (value.name.indexOf('张') === 0) {
                    context.commit('PersonAdd', value)
                } else { alert('请输入姓张的人') }
            },
            addPersonServer(context) {
                axios({
                    methods: 'get',
                    url: 'https://api.uixsj.cn/hitokoto/get?type=social'
                }).then(response => {
                    context.commit('PersonAdd', { id: nanoid(), name: response.data })
                }, error => {
                    alert(error.message)
                })
            }
        },
        mutations: {
            PersonAdd(state, value) {
                state.persons.unshift(value)
            }
        },
        state: {
            persons: [{ id: "001", name: '张三' }]
        },
        getters: {
            firstPersonName(state) {
                return state.persons[0].name
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    记录:Unity脚本的编写4.0
    基于SSM跨境电商网站的设计与实现/海外购物平台的设计
    [模拟赛]2022.07.25
    Java并发Map的面试指南:线程安全数据结构的奥秘
    Unity进阶第二章-消息框架(实现角色吃金币功能)
    聊聊并发编程——多线程之volatile
    java基础-并发编程-CyclicBarrier(JDK1.8)源码学习
    Java回顾-面向对象(抽象类与抽象方法/接口/内部类)
    Maven问题相关 1 存在jar 却无法映射
    【Python大数据笔记_day10_Hive调优及Hadoop进阶】
  • 原文地址:https://blog.csdn.net/Zhang_wang_yun/article/details/130546262