状态管理Vuex(简单易懂看这边就够了)

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

Vuex的核心:state、mutations、actions

  • state:存储公共的一些数据

  • mutations:定义一些方法来修改state中的数据,数据怎么改变

  • actions: 使用异步的方式来触发mutations中的方法进行提交。

此部分的代码我们在vue-cli中使用

6.1 state状态

声明:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count:0
  },
  mutations: {

  },
  actions: {

  }
})

使用

  • 直接在模板中使用

<template>
  <div>
      vuex中的count:{{$store.state.count}}
  </div>
</template>

 在方法中使用

methods:{
    func1(){
        console.log(this.$store.state.count);
    }
}

在计算属性中使用

当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键。

// 在组件中导入mapState函数。mapState函数返回的是一个对象
import {mapState} from 'vuex'
// 在组件的计算属性中使用mapState
computed:mapState({
    count:'count', // 直接使用
    mycount(state){
        // 计算后使用。initcount是本地的一个属性
        return state.count + this.initcount
    }
})

使用展开运算符:

在之前的示例中,不方便和本地的计算属性混合使用,下面我们使用展开运算符,这样就可以和本地的计算属性一起使用。

   computed:{
        localCount(){
            return this.initcount-1;
        },
        ...mapState({
            count:'count',
            mycount(state){
                return state.count + this.initcount
            }
        })
    }

6.2 mutations

state中的数据是只读的,不能直接进行修改。想要修改state中数据的唯一途径就是调用mutation方法。

使用commit()函数,调用mutation函数。

注意:mutation中只能执行同步方法。

  • 在mutations中定义方法,在方法中修改state

  mutations: {
    // state是状态,num是额外的参数
    add(state, num){
      state.count = state.count + num
    }
  },

直接调用

    methods:{
        func2(){
            this.$store.commit('add',2);
        }
    },

使用辅助函数(mapMutations)简化

import {mapMutations} from 'vuex'
    methods:{
        func1(){
            console.log(this.$store.state.count);
        },
        func2(){
            this.$store.commit('add',2);
        },
        ...mapMutations({
            addFunc:'add',  // 将 `this.addFunc()` 映射为 `this.$store.commit('add')`
            reduceFunc:'reduce'
        })
    },

如果暴露的方法和mutations中的方法名一致,可以使用数组的方式

   methods:{
        func1(){
            console.log(this.$store.state.count);
        },
        func2(){
            this.$store.commit('add',2);
        },
        ...mapMutations([
            'add',  // 将 `this.add()` 映射为 `this.$store.commit('add')`
            'reduce'
        ])
    },

6.3 actions

  • actions中执行的方法可以是异步的

  • actions中要修改状态state中的内容,需要通过mutation。

  • 在组件中调用action需要调用dispatch()函数。

步骤如下:

  • 声明action方法

  actions: {
    delayAdd(context,num){
      // 延时两秒增加
      setTimeout(function(){
        // 调用mutations中的方法
        context.commit('add',num)
      },2000)
    }
  }

 直接调用action方法

func3(){
    this.$store.dispatch('delayAdd',2)
},

使用辅助函数mapActions调用

import {mapActions} from 'vuex'
 methods:{
        func3(){
            this.$store.dispatch('delayAdd',2)
        },
        ...mapActions({
            delayAddLocal:'delayAdd' // 将 `this.delayAddLocal()` 映射为 `this.$store.dispatch('delayAdd')`
        })
    },

6.4 getters

vuex中的计算属性。

  • 在vuex中声明getter方法

 getters:{
    doubleCount(state){
      return state.count*2
    }
  }

在组件中获取getter

func4(){
    console.log(this.$store.getters.doubleCount);
},

6.5 modules

在复杂的项目中,我们不能把大量的数据堆积到store中,这样store的内容就太多,而且比较凌乱,不方便管理。所以就是出现了module。他将原有的store切割成了一个个的module。每个module中都有自己的store、mutation、actions和getter

  • 定义一个module

const storeModuleA = {
    state:{
        countA:10
    },
    mutations:{
        addA(state){
            state.countA++
            console.log("moduleA:"+state.countA);
        },
        // 此方法和root中的方法名字一致
        add(state){
            console.log("moduleA:"+state.countA);
        }
    }
}

export default storeModuleA;

 在store.js中,导入并注册此module

import Vue from 'vue'
import Vuex from 'vuex'
import storeModuleA from './storeModuleA'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count:0
  },
  mutations: {
    // state是状态,num是额外的参数
    add(state, num){
      state.count = state.count + num
    }
  },
  actions: {
  },
  getters:{
    doubleCount(state){
      return state.count*2
    }
  },
  modules:{
    a:storeModuleA
  }
})

在组件中使用子模块中的状态

func6(){
    console.log(this.$store.state.a.countA);
},

在组件中使用子模块的mutation

  • 没有声明namespace的情况

    • 子模块中的mutation在没有使用namespace的情况下,这些方法会注册到root中。

    • 如果子模块中的mutation和root中的一样。则都会被调用。

func6(){
    console.log(this.$store.state.a.countA);
    this.$store.commit('addA'); // 和root中不一样的mutation方法
    this.$store.commit('add'); // 和root中一样的mutation方法
},

声明namespace的情况

在module中添加

namespaced:true

在组件中调用,加上别名即可

this.$store.commit('a/addA');

 结束语:
  首先,恭喜大家已经看完整个(状态管理Vuex),一般而言,不管书籍也好,能够完整跟下来的就已经很不容易了。所以尽量帮助初学者减少初级的困难,其实一旦掌握了之后,会发现它其实是非常容易。但大道至简,知易行难,需要大家之后不断练习,在此基础上加强知识的认知深度。虽然我尽量以通俗易通的形式,将内容体现出来,但水平毕竟有限,望大家海涵。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值