Vue Vuex搭建vuex环境及vuex求和案例分享

目录
  • Vuex介绍
    • 概念
    • 何时使用
  • 多个组件需要共享数据时
    • 求和案例–纯vue版
      • 搭建vuex环境
        • 求和案例–vuex版
          • 一些疑惑和问题

            Vuex介绍

            概念

            在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读写),也是一种组件间通信的方式,且适用于任意组件间通信

            何时使用

            多个组件需要共享数据时

            求和案例–纯vue版

            新建 Count.vue 组件,并在 App.vue 中注册引用

            <template>
              <div>
                <Count/>
              </div>
            </template>
            
            <script>
            import Count from "@/components/Count";
            
            export default {
              name: 'App',
              components: {Count},
            }
            </script>
            
            <style>
            
            </style>

            我们主要关注 Count.vue

            <template>
              <div class="category">
                <h1>当前求和为:{{ sum }}</h1>
                <select v-model="n">
                  <!--这里的value前有冒号,否则value值是字符串-->
                  <option :value="1">1</option>
                  <option :value="2">2</option>
                  <option :value="3">3</option>
                </select>
            
                <!--v-model.number收集到的数据强转为number-->
            <!--    <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,//用户选择的数字
                  sum: 0,//当前和
                }
              },
              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 scoped>
            select, button {
              margin-right: 5px;
            }
            </style>

            搭建vuex环境

            注意:

            vue2 中要使用 vuex 的 3 版本
            vue3 中要使用 vuex 的 4 版本

            因为我们使用的是 vue2 所以我们需要安装 vuex 的 3 版本

            • 1、执行 npm i vuex@3 来安装 vuex 3 版本
            • 2、src 下创建 store 文件夹,在其中创建一个 index.js

            index.js

            //该文件用于创建vuex中最为核心的store
            
            //引入vuex
            import Vuex from 'vuex'
            //引入vue
            import Vue from "vue";
            //应用vuex插件
            Vue.use(Vuex)
            
            //准备actions;用于相应组件中的动作
            const actions = {}
            //准备mutations;用于操作数据(state)
            const mutations = {}
            //准备state;用于存储数据
            const state = {}
            
            //创建并暴露store
            export default new Vuex.Store({
                actions:actions,
                mutations,//key和value重名了,简写
                state,//key和value重名了,简写
            });

            3、main.js 中引入刚才写好的 store

            ......
            //引入store
            //import store from './store/index'
            import store from './store'
            
            ......
            
            //创建vm
            new Vue({
                el: "#app",
                //store:store
                store,//触发简写形式
                ......
            })

            运行项目,我们可以打印 vm 和 vc,可以看到 $store

            求和案例–vuex版

            我们将求和的案例改为 vuex 版本

            1、首先把数据交给 state

            所以我们把 Count 组件中的数据 sum 变量剪切走放到 index.js 中的 state 中,同时 Count 组件中的方法,例如加法 increment 中使用 this.$store.dispatch("方法名",变量) 来替代原来的方法。这样就走完了流程图中以下部分

            Count.vue

            <template>
              <div class="category">
                <h1>当前求和为:{{$store.state.sum}}</h1>
                ......
              </div>
            </template>
            
            <script>
            export default {
              name: "Count",
              data() {
                return {
                  n: 1,//用户选择的数字
                }
              },
              methods: {
                increment() {
                  this.$store.dispatch("jia",this.n);
                }
                ......
              }
            }
            </script>

            同时 index.js 中的 action 中添加对应的方法名,从图上的流程图来看,actions 中的东西会交到 mutations 中处理,所以需要手动调用 commit方法

            mutation 中也需要增加同样的方法名,这里可以都改成大写,做个区分。方法中第一个参数就是 state,方法中处理真实逻辑即可

            index.js

            //该文件用于创建vuex中最为核心的store
            
            //引入vuex
            import Vuex from 'vuex'
            //引入vue
            import Vue from "vue";
            //应用vuex插件
            Vue.use(Vuex)
            
            //准备actions;用于相应组件中的动作
            const actions = {
                /*jia:function () {
                }*/
                //简写为:
                jia(context,value){
                    console.log("actions中的jia被调用了",context,value);
                    context.commit("JIA",value)
                }
            }
            //准备mutations;用于操作数据(state)
            const mutations = {
                JIA(state,value){
                    console.log("mutations中的JIA被调用了",state,value);
                    state.sum += value;
                }
            }
            
            //准备state;用于存储数据
            const state = {
                sum: 0,//当前和
            }
            
            //创建并暴露store
            export default new Vuex.Store({
                actions:actions,
                mutations,//key和value重名了,简写
                state,//key和value重名了,简写
            });

            log 输出:

            运行程序:

            我们根据以上思路完善其他方法

            Count.vue

            <template>
              <div class="category">
                <h1>当前求和为:{{$store.state.sum}}</h1>
                <select v-model="n">
                  <!--这里的value前有冒号,否则value值是字符串-->
                  <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.dispatch("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 scoped>
            select, button {
              margin-right: 5px;
            }
            </style>

            index.js

            //该文件用于创建vuex中最为核心的store
            
            //引入vuex
            import Vuex from 'vuex'
            //引入vue
            import Vue from "vue";
            //应用vuex插件
            Vue.use(Vuex)
            
            //准备actions;用于相应组件中的动作
            const actions = {
                /*jia:function () {
                }*/
                //简写为:
                jia(context,value){
                    console.log("actions中的jia被调用了");
                    context.commit("JIA",value)
                },
                jiaOdd(context,value){
                    console.log("actions中的jianOdd被调用了");
                    if(context.state.sum % 2){
                        context.commit("JIA",value)
                    }
                },
                jiaWait(context,value){
                    console.log("actions中的jianWait被调用了");
                    setTimeout(() => {
                        context.commit("JIA",value)
                    }, 500)
                }
            }
            //准备mutations;用于操作数据(state)
            const mutations = {
                JIA(state,value){
                    console.log("mutations中的JIA被调用了",state,value);
                    state.sum += value;
                },
                JIAN(state,value){
                    console.log("mutations中的JIAN被调用了",state,value);
                    state.sum -= value;
                }
            }
            
            //准备state;用于存储数据
            const state = {
                sum: 0,//当前和
            }
            
            //创建并暴露store
            export default new Vuex.Store({
                actions:actions,
                mutations,//key和value重名了,简写
                state,//key和value重名了,简写
            });

            到此为止,功能就实现了,你发现了吗,这里做了些优化,由于 index.js 中的 jia、jian方法里边什么都没做,直接就 commit 给了 mutation,而 vc 是可以直接对话 Mutations 的,如下图:

            所以我们把 index.js 中 actions 中的 jian方法去掉,在 Count 中直接调用 mutation 中的方法,也就是我们把 jian方法去掉,在 Count 的 decrement 方法中直接调用 commit 了

            decrement() {
                this.$store.commit("JIAN",this.n);
            },

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

            一些疑惑和问题

            index.js 中的上下文有什么作用?我们可以打印下 context:

            可以看到其中有dispatch、commit、state这些熟悉的身影。我们用 jiaOdd 举例,当方法逻辑处理复杂时,可以继续 dispatch 其他方法来分担。而有了 state 我们可以拿到其中的 sum 值:

                jiaOdd(context,value){
                    console.log("actions中的jianOdd被调用了",context);
                    if(context.state.sum % 2){
                        context.commit("JIA",value)
                    }
                    context.dispatch("demo",value)
                },
                demo() {
                    //处理一些事情
                },
            

            本文转自网络,如有侵权请联系客服删除。