Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue教程24:Vuex Modules(完结) #25

Open
chencl1986 opened this issue Mar 18, 2019 · 0 comments
Open

Vue教程24:Vuex Modules(完结) #25

chencl1986 opened this issue Mar 18, 2019 · 0 comments

Comments

@chencl1986
Copy link
Owner

阅读更多系列文章请访问我的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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant