阅读更多系列文章请访问我的GitHub博客,示例代码请访问这里

该节教程代码可通过npm start运行devServer,在http://localhost:8080/#/index查看效果

运行服务端请cd server,node server.js。

创建Vuex模块

我们可以新建两个Vuex模块,名为src/store/mod_a.js和src/store/mod_b.js。
每个Vuex模块都可以看做一个独立的store对象,里面可以有属于它自己的State、Actions、Mutations等等。

代码示例:/lesson24/src/store/mod_a.js

新建模块代码如下:

export default {
  state: {
    str: 'store_a'
  },
  mutations: {
    'mod_a.setStr': function (state, s){
      alert('a的setStr');
      state.str=s;
    }
  },
  actions: {
    'mod_a.setStr': function ({commit}, s){
      commit('mod_a.setStr', s);
    }
  }
}

在实例化Store对象时,可以引入模块。

import ModA from './mod_a'
import ModB from './mod_b'

同时将模块配置到Store中:

export default new Vuex.Store({
  modules: {
    mod_a: ModA,
    mod_b: ModB
  }
})

读取模块数据

代码示例:/lesson24/src/components/Index.vue

在组件中,就可以通过$store.state.mod_a.str读取到模块内的state。

a_str: {{$store.state.mod_a.str}}<br>
b_str: {{$store.state.mod_b.str}}<br>

当然更推荐的是使用mapState的方式读取,但是和直接读取Store下的值(…mapState([‘a’, ‘b’]))不同,读取模块中的State需要通过方法获取:

computed: {
  ...mapState({
    str_a: state=>state.mod_a.str,
    str_b: state=>state.mod_b.str,
  }),
}

这样就可以在template中通过str_a和str_b获取到模块的state。

a_str: {{str_a}}<br>
b_str: {{str_b}}<br>

触发一个Action

假设每个模块中都有一个名为setStr的Action,我们在运行this.$store.dispatch(‘setStr’, ‘test’)时,所有模块中的同名Action都会被执行。

Mutation也具有同样的特点。但这不是Vuex的Bug,它的用意是让使用者能够通过一个Action同时更新多个模块的数据。

若需要回避这个问题,则可以给每个模块中的Action单独命名,通常我们会加上模块名作为前缀:

代码示例:/lesson24/src/store/mod_a.js

export default {
  state: {
    str: 'store_a'
  },
  mutations: {
    'mod_a.setStr': function (state, s){
      alert('a的setStr');
      state.str=s;
    }
  },
  actions: {
    'mod_a.setStr': function ({commit}, s){
      commit('mod_a.setStr', s);
    }
  }
}

在使用时,只需要分别mapActions:

代码示例:/lesson24/src/components/Index.vue

此时有两种方法可以mapActions:

  1. …mapActions([‘mod_a.setStr’, ‘mod_b.setStr’])。
    此时需要通过methods运行\this[‘mod_a.setStr’](str)来触发Action。此时需要通过methods运行\this[‘mod_a.setStr’](str)来触发Action。
    但在template中直接调用,如<input type=“button” value=“设置A” @click="‘mod_b.setStr’">会报错。
  2. …mapActions({ set_a: ‘mod_a.setStr’, set_b: ‘mod_b.setStr’ })。
    这种方法的好处是,由于已经替换了方法名,在template中可以直接调用,如<input type=“button” value=“设置A” @click=“set_a(‘aaa’)”>

完整示例代码如下:

<template>
  <div>
    str: {{$store.state.str}}<br>
    a_str: {{$store.state.mod_a.str}}<br>
    b_str: {{$store.state.mod_b.str}}<br>
    a_str: {{str_a}}<br>
    b_str: {{str_b}}<br>
    <input type="button" value="设置A" @click="setA('aa')">
    <input type="button" value="设置B" @click="setB('bb')"><br/>
    <input type="button" value="设置A" @click="set_a('aaa')">
    <input type="button" value="设置B" @click="set_b('bbb')">
  </div>
</template>

<script>
import {mapState, mapActions, mapGetters} from 'vuex';

export default {
  name: 'Index',
  data () {
    return {
      
    }
  },
  async created(){
    await this.readUsers();
  },
  methods: {
    ...mapActions(['addA', 'addB', 'setOnline', 'readUsers', 'mod_a.setStr', 'mod_b.setStr']),
    ...mapActions({
      set_a: 'mod_a.setStr',
      set_b: 'mod_b.setStr'
    }),
    setA(str) {
      this['mod_a.setStr'](str)
    },
    setB(str) {
      this['mod_b.setStr'](str)
    },
  },
}
</script>
Logo

前往低代码交流专区

更多推荐