Vuex

作者: lyp82nkl | 来源:发表于2019-07-16 22:15 被阅读0次

    Vuex 是什么

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    判断是否要使用 Vuex

    如果项目中组件比较多,并且组件之间需要共享状态,那么就需要用到 Vuex。或者说,如果项目没有使用 Vuex 也依然能够完成,那么就不需要使用 Vuex 。

    Vuex基本使用流程

    安装

    npm install vuex

    创建store仓库,并在vue中挂载
       //  src/store/index.js
     import Vuex from 'vuex'
     import Vue from 'vue'
    
     Vue.use(Vuex)
     
     const store = new Vuex.Store({
    // “Vuex.Store” 首字母要大写,不要随意更改
         state: {
    // state 中是需要记录的数据
             number: 1
         }
     })
     export default store
     
     // src/main.js
     import store from '@/store'
     new Vue({
         // ...
         store
     })
    

    在组件中使用state数据

    vuex通过computed计算属性监测数据的变化,进而影响到所有组件中数据的状态

    计算属性中使用this.$store.state获取
     computed: {
         number () {
             return this.$store.state.number
         }
     }
    
    借助辅助函数mapState实现
     import { mapState } from 'vuex'
     
     computed: {
         ...mapState([
             'number'
         ])
     }
    
    在store中定义mutations,改变state状态
     new Vuex.Store({
         // ...
         mutations: {
             plus (state) {
                 state.number++
             }
         }
     })
    
    在各个组件中可以通过提交mutations改变state数据

    栗子:

    // src/App.vue
     <template>
         <div id="a-com">
             <h3>state的number: {{ number }}</h3>
             <a-com></a-com>
             <b-com></b-com>
         </div>  
     </template>
     <script>
     import { mapState } from 'vuex'
     import ACom from '@/components/ACom
     import BCom from '@/components/BCom
     export default {
         name: 'App',
         computed: {
             ...mapState([
                 'number'
             ])
         },
         components: {
             ACom,
             BCom
         }
     }
     </script>
     
     // src/components/ACom.vue
     <template>
         <div id="a">
             <h3>A组件的number: {{ number }}</h3>
             <button @click="plusNumber">+</button>
         </div>  
     </template>
     <script>
     import { mapState, mapMutations } from 'vuex'
     export default {
         name: 'A',
         computed: {
             ...mapState([
                 'number'
             ])
         },
         methods: {
             // 返回需要的mutations函数
             ...mapMutaions([
                 'plus'
             ]),
             plusNumber () {
                 // 1. 直接通过store提交mutations
                 // 此处plus是mutations中的方法
                 // this.$store.commit('plus')
                 
                 // 2. 使用mapMutations辅助函数 this.plus()
             }
         }
     }
     </script>
    

    在src/components/BCom.vue中定义相同的结构



    当点击A+或者B+的按钮时都会触发数据仓库state中的number变化

    通过vuex我们在不同的组件中共享了数据,实现了某个组件改变数据时,其他组件同时响应

    Vuex 状态管理流程:view => actions => mutations => state => view

    栗子:

    const store =  new Vuex.Store({
        state: {    // state 用来保存状态
          num: 88
        },
    
        getters: {    // 可以对 state 中的数据做一些约束
          getNum (state) {  // 这里传的参数是 state
            return state.num > 0 ? state.num : 0
          }
        },
    
        mutations: {    // mutations 可以直接改变 state 中的状态,里面定义改变状态的函数
          increase (state) {  // 这里传的参数是 state
            state.num += 10
          },
          decrease (state) {
            state.num -= 10
          }
        },
    
        actions: {    // actions 中只能对 mutations 进行操作,而不能直接改变 state 中的状态
          increaseAction (context) {  // 这里传的参数是上下文对象(context)
              context.commit('increase')  // 使用 context,提交 increase 方法
          },                              // 这里提交的increase 方法对应 mutations 中的 increase 方法
          decreaseAction (context) {
              context.commit('decrease')
          }
        }
    
      })
    

    获取 state 中保存的数据

    this.$store.state.xxx  // xxx 为 state 中的键值
    
    如上例中:
    this.$store.state.num
    

    获取 getters 中保存的数据

    this.$store.getters.xxx  // xxx 为 getters 中的函数名
    
    如上例中:
    this.$store.getters.getNum
    

    触发 mutations 中的函数

    this.$store.commit('xxx')  // xxx 为函数名
    
    如上例中:
    this.$store.commit('increase')
    

    触发 actions 中的函数

    this.$store.dispatch('xxx')  // xxx 是函数名
    
    如上例中:
    this.$store.dispatch('increaseAction')
    

    mutations 和 actions 的区别

    函数传递的参数不同
    • mutations 中的函数传的是 state;
    • actions 中的函数传的是 context;
    触发方式不同
    • 触发 mutations 中的函数,通过 this.$store.commit('xxx');
    • 触发 actions 中的函数,通过 this.$store.dispatch('xxx');
    mutations 中只能包含同步操作,actions 中可以包含异步操作

    mutations

    mutations: {    
      increase (state) {  
        state.num += 10
      },
      decrease (state) {
        state.num -= 10
      }
    }
    

    actions

    actions: {
      increaseAction (context) {
        setTimeout(function () {  // 异步操作
          context.commit('increase')
        }, 1000)
      },
      decreaseAction (context) {
        setTimeout(function () {
          context.commit('decrease')
        }, 1000)
      }
    }
    

    操作对象不同

    • mutations 可以直接操作 state;
    • actions 不能直接操作 state,而是操作 mutations。

    vuex的应用场景

    检测用户是否登录

    当在登录组件中处理了登录信息后,存入state仓库中,可在所有的组件中进行用户数据共享,判断是否有权限

    非父子组件值传递

    其实父子组件中也是可以使用vuex,主要看业务的复杂度

    相关文章

      网友评论

          本文标题:Vuex

          本文链接:https://www.haomeiwen.com/subject/dphxlctx.html