了解vuex

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

简单点说,vuex就是一个全局共享的储存库,当在较为复杂的程序中开始时,有时候会涉及到组件间的传值,或者有些方法可能需要在各个组件中都会应用到,这个时候就可以把这个值存在vuex储存库里,其他组件如果想去使用这个值,就可以直接从vuex中获取,少去了许多不必要的步骤。

五大核心概念与基本用法

一、state

vuex的基本数据,用来储存变量,相当于data

获取state的变量

可以通过this.$store.state.变量得到变量
也可以定义在computed计算属性里获取到vuex的state变量

export default{
  computed:{
    value(){
      return this.$store.state.value//value即state储存的变量
    }
  }
}

二、mutations

操作或者修改state数据的方法,只做同步操作,相当于methods里的方法

获取mutations的方法

可以通过this.$store.commit('mutations方法名',参数)得到方法
如下例小demo:

<template>
  <div>
    点赞数:{{$store.state.count}}
    <button @click='add(1)'>赞</button>
  </div>
</template>
export default{
  methods:{
    add(num){
      this.$store.commit('vuex方法名',num)
    }
  }
}

mutations里的写法

export default new Vuex.Store({
  state: {
    count:0
  },
  mutations: {
    add(state,num){
      state.count+=num;
    }
  }
})

上述例子为点赞实例,点赞数保存在state里,使用mutations的方法自增

三、getters

从基本数据派生的数据,相当于computed里的(计算)属性

获取getters的属性

可以通过this.$store.getters.值得到
如下例小demo:

<template>
  <div>
    计算的和为:{{$store.state.getters.sum}}
  </div>
</template>

getters里的写法

export default new Vuex.Store({
  state: {
    count:0,
    a:100,
    b:2
  },
  getters:{
    sum(state){
      return state.count + state.a * state.b;
    }
  }
})

四、actions

类似于mutation,提交的是mutation,用于做异步操作,可包含任意异步操作

获取actions的方法

可以通过this.$store.dispatch('actions方法名')得到
如下例小demo:

<template>
  <div>
    点赞数:{{$store.state.count}}
    <button @click='$store.dispatch("actionA")'>赞</button>
  </div>
</template>

actions里的写法

export default new Vuex.Store({
  state: {
    count:0
  },
  mutations: {
    add(state,num){
      state.count+=num;
    }
  },
  actions:{
    actionA({commit}){
      commit('add',1000);//异步执行add方法
    }
  }
})

五、modules

模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理

如何使用?

多个模块,则定义多个module,结构如下:

//模块A
const moduleA = {
  namespaced:true,//开启带命名空间的模块,否则无法使用命名调用模块数据
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}
//模块B
const moduleB = {
  namespaced:true,//开启带命名空间的模块,否则无法使用命名调用模块数据
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
})

1、获取state

this.$store.a.值

2、获取getters

this.$store.getters['a/值']

3、获取mutations

this.$store.commit('a/方法')

4、获取actions

this.$store.dispatch('a/方法')

进阶用法

上面举例的vuex的基本用法,但是发现如果在每个组件里都要写this.$store.xxx.xxx('xxx')很麻烦,而且很长,可以使用vuex提供的辅助方法来简短化代码。

一、单模块调用

<template>
  <div>
    {{state1}},{{state2}}
    {{getter1}},{{getter2}}
    <button @click='mutation1'>执行mutation1</button>
    <button @click='mutation2'>执行mutation2</button>
    <button @click='action1'>执行action1</button>
    <button @click='action2'>执行action2</button>
  </div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
  computed:{
    //假设vuex里的state有state1和state2
    ...mapState(['state1','state2']),
    //假设vuex里的getters有state1和state2
    ...mapGetters(['getter1','getter2'])
  },
  methods:{
    //假设vuex里的mutations有mutation1和mutation2函数
    ...mapMutations(['mutation1','mutation2']),
    //假设vuex里的actions有action1和action2函数
    ...mapActions(['action1','action2'])
  }
}
</script>

二、多模块调用

<template>
  <div>
    {{stateA}},{{stateB}}
    {{getterA}},{{getterB}}
    <button @click='mutationA'>执行mutationA</button>
    <button @click='mutationB'>执行mutationB</button>
    <button @click='actionA'>执行actionA</button>
    <button @click='actionB'>执行actionB</button>
  </div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
  computed:{
    ...mapState({
      stateA:state=>state.a.stateA,//模块a里state属性里的stateA值
      stateB:state=>state.b.stateB//模块b里state属性里的stateB值
    }),
    ...mapGetters({
      getterA:'a/getterA',//模块a里getters属性里的getterA值
      getterB:'b/getterB'//模块b里getters属性里的getterB值
    })
  },
  methods:{
    ...mapMutations({
      mutationA:'a/mutationA',//模块a里mutations属性里的mutaionA方法
      mutationB:'b/mutationB'//模块b里mutations属性里的mutaionB方法
    }),
    ...mapActions({
      actionA:'a/actionA',//模块a里actions属性里的actionA方法
      actionB:'b/actionB'//模块b里actions属性里的actionB方法
    }),
  }
}
</script>

最后强调:
使用模块命名调用数据记得把namespaceds设置为true
...mapState...mapGetters写在computed
...mapMutations...mapAction写在methods

收工!