简述Vue中使用Vuex

1、为什么要用vuex

      在vue组件通信的过程中,我们通信的目的往往就是在组件之间传递数据或组件的状态(这里将数据和状态统称为状态),进而更改状态。但可以看到如果我们通过最基本的方式来
进行通信,一旦需要管理的状态多了,代码就会变得十分混乱。对所有状态的管理便会显得力不从心,尤其是多人合作的时候。此时vuex出现了,他就是帮助我们把公用的状态全抽出来放
在vuex的容器中,然后根据一定的规则来进行管理。

2、概念

  • 概念:vuex是一个状态管理工具,每一个Vuex应用的核心就是store(仓库);“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state),它的实例是唯一的-----单例模式;  一般把需要共享的数据放到store中;
  • 功能:存数据、取数据、改数据;
  • 出现场景:
    • 涉及到非父子关系的组件,例如兄弟关系、祖孙关系,甚至更远的关系组件之间的联系;
    • 在大型单页应用中,考虑如何更好地在组件外部管理状态;
  • 注意:vuex的数据处理流程是一个"单向"的数据流 ;
  • vuex的核心:
    • state:存放数据(状态);    取数据  this.$store.state.变量名
    • mutations:存放如何更改状态,同步方法放到mutations(同步)里面;    调用方法 this.$store.commit("方法名","参数")
    • getters:相当于计算属性,从state中派生出状态,比如将state中的某个状态进行过滤然后获取新的状态;      this.$store.getters.方法名(sum)
    • actions:mutations的加强版,异步方法放在了actions(动作)里面;      调用方法this.$store.dispatch("方法名"),异步方法则会调用mutations里面的同步方法
    • modules:就是当用这个容器来装这些状态还是显得混乱的时候,我们就可以把容器分成几块,把状态和管理规则分类来装。这和我们创建js模块是一个目的,让代码结构更清晰。

3、基本使用

  • vuex的安装
    cnpm i vuex --save
  • 安装成功后,
    • 新手入门
      • 新建store文件夹,内容如下

                               

      • 在app.js里面进行引入
        import store from './store'
        new Vue({
            router,
            i18n,
            store,
            el: '#app',
            render: h => h(App)
        })
      • store文件夹中index.js的内容为
        import Vue from 'vue'
        import Vuex from 'vuex'
        
        import state from './state'
        import actions from './actions'
        import mutations from './mutations'
        
        Vue.use(Vuex)
        
        export default new Vuex.Store({
            state,
            actions,
            mutations
        })
      • 在state.js中定义状态
        export default {
            count: 1,
        }
      • 在mutations.js里面定义同步方法
        export default {
            // 改变状态的执行者   用于同步更改状态
            stateMutationsAdd(state, payLoad) {
                // 第一个参数是state   第二个参数是调用mutations时传入的参数
                state.count += payLoad;
            },
            stateMutationsReduce(state, payLoad) {
                state.count -= payLoad;
            }
        }
      • 在actions.js里面定义异步操作
        export default {
            // actions并不直接更改状态   而是发起mutations来更改状态
            stateAsyncReduce(context) {
                // context 是一个与 store 实例具有相同方法和属性的 context 对象
                // 这个异步操作  我们可以发送http请求、定时器、
                setTimeout(() => {
                    context.commit("stateMutationsReduce", 5)//不能用this.$store,为undefined
                }, 1000)
            }
        }
      • 在vue组件中使用(将state与getters结合进组件需要使用计算属性,将mutations与actions结合进组件需要在methods里面进行调用)
        <template>
          <div class="home">
            <div class="block">
              <h1>vuex的基本使用</h1>
              <el-button size="mini" type="primary" @click="reduceNumber">-</el-button>
              &nbsp;&nbsp;{{count}}
              <el-button size="mini" type="primary" @click="addNumber">+</el-button>
              <h1>vuex练习结束</h1>
            </div>
          </div>
        </template>
        <script>
        export default {
          name: "home",
          data() {
            return {};
          },
          computed: {
            count() {
              return this.$store.state.count;
            }
          },
          methods: {
            /**
             * [addNumber  对count数据进行增加操作  采用同步方式]
             * @return {[type]} [description]
             */
            addNumber() {
              // 第一个参数是同步方法的名称   第二个参数是传递给方法的数据
              this.$store.commit("stateMutationsAdd", 10);
            },
            /**
             * [reduceNumber  对count数据进行减少操作   采用异步方式]
             * @return {[type]} [description]
             */
            reduceNumber() {
              // dispatch返回的是actions执行的结果,是一个promise对象,如果异步操作之后还需要其他操作,可以使用.then/.catch等
              this.$store.dispatch("stateAsyncReduce");
            }
          },
          mounted() {}
        };
        </script>
        View Code
      • 效果图

                             

        点击 + 进行同步增加     

        点击-进行异步减少,每隔1s减少5

    • 新手入门之后,我们可以尝试将mutations里面的一些方法名称提取出来,从而提高代码维护性;
      • state.js
        export default {
            count: 1,
        }
      • mutation-types.js
        export const STATE_MUTATIONS_ADD = 'stateMutationsAdd'
        export const STATE_MUTATIONS_REDUCE = 'stateMutationsReduce'
      • mutations.js
        import { STATE_MUTATIONS_ADD, STATE_MUTATIONS_REDUCE } from './mutation-types'
        export default {
            // 改变状态的执行者   用于同步更改状态
            [STATE_MUTATIONS_ADD](state, payLoad) {
                // 第一个参数是state   第二个参数是调用mutations时传入的参数
                state.count += payLoad;
            },
            [STATE_MUTATIONS_REDUCE](state, payLoad) {
                state.count -= payLoad;
            }
        }
        View Code
      • actions.js
        import { STATE_MUTATIONS_ADD, STATE_MUTATIONS_REDUCE } from './mutation-types'
        export default {
            // actions并不直接更改状态   而是发起mutations来更改状态
            stateAsyncReduce(context) {
                // context 是一个与 store 实例具有相同方法和属性的 context 对象
                // 这个异步操作  我们可以发送http请求、定时器、
                setTimeout(() => {
                    context.commit(STATE_MUTATIONS_REDUCE, 5)//不能用this.$store,为undefined
                }, 1000)
            }
        }
        View Code
      • vue组件中的使用
        <template>
          <div class="home">
            <div class="block">
              <h1>vuex的基本使用</h1>
              <el-button size="mini" type="primary" @click="reduceNumber">-</el-button>
              &nbsp;&nbsp;{{count}}
              <el-button size="mini" type="primary" @click="addNumber">+</el-button>
              <h1>vuex练习结束</h1>
            </div>
          </div>
        </template>
        <script>
        import {
          STATE_MUTATIONS_ADD,
          STATE_MUTATIONS_REDUCE
        } from "../store/mutation-types";
        export default {
          name: "home",
          data() {
            return {};
          },
          computed: {
            count() {
              return this.$store.state.count;
            }
          },
          methods: {
            /**
             * [addNumber  对count数据进行增加操作  采用同步方式]
             * @return {[type]} [description]
             */
            addNumber() {
              // 第一个参数是同步方法的名称   第二个参数是传递给方法的数据
              this.$store.commit(STATE_MUTATIONS_ADD, 10);
            },
            /**
             * [reduceNumber  对count数据进行减少操作   采用异步方式]
             * @return {[type]} [description]
             */
            reduceNumber() {
              // dispatch返回的是actions执行的结果,是一个promise对象,如果异步操作之后还需要其他操作,可以使用.then/.catch等
              this.$store.dispatch("stateAsyncReduce");
            }
          },
          mounted() {}
        };
        </script>
        View Code
    • 为了方便起见,利用vuex提供的mapState、mapGetters、mapMutations以及mapActions四个方法将这些功能结合进组件
      • 其他文件跟上述保持一致
      • vue组件中的使用

4、遇到的问题

猜你喜欢

转载自www.cnblogs.com/wxh0929/p/11984417.html
今日推荐