Vuex学习总结 - Modules(7)

4.Vuex核心概念

4.5 Modules

Vuex实例允许划分为多个模块。
每个模块包含自己的statemutationsactionsgetters、嵌套modules

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB,
  },
  state: {
    count: 0,
  },
})
// store/modules/moduleA.js
export default {
    state: {
        count: 10,
    },
    mutations: {

    },
    getters: {

    },
    actions: {

    },
}
// store/modules/moduleB.js
export default {
    state: {
        count: 20,
    },
    mutations: {

    },
    getters: {

    },
    actions: {

    },
}
<template>
    <div>
        模块A的count:{{this.$store.state.a.count}}
        <br/>
        模块B的count:{{this.$store.state.b.count}}
    </div>
</template>

<script>
    export default {
        name: "ModulesDemo"
    }
</script>

尝试提交模块的mutation

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB,
  },
  state: {
    count: 0,
  },
  mutations: {
    increment(state) {
      state.count++
    },
  },
})
// store/modules/moduleA.js
export default {
    state: {
        count: 10,
    },
    mutations: {
        increment(state) {
            state.count++
        }
    },
}
<template>
    <div>
        模块A的count:{{this.$store.state.a.count}}
        <br/>
        模块B的count:{{this.$store.state.b.count}}
        <br/>
        Vuex实例的count:{{this.$store.state.count}}
        <br/>
        <button @click="increment">加一</button>
    </div>
</template>

<script>
    export default {
        name: "ModulesDemo",
        methods: {
            increment() {
                this.$store.commit('increment')
            }
        },
    }
</script>

注意到这里在组件中提交mutation,Vuex实例及其modules中的mutation都会被触发。

添加命名空间。

// store/modules/moduleA.js
export default {
    namespaced: true,

    state: {
        count: 10,
    },
    mutations: {
        increment(state) {
            state.count++
        }
    },
}
<template>
    <div>
        模块A的count:{{this.$store.state.a.count}}
        <br/>
        模块B的count:{{this.$store.state.b.count}}
        <br/>
        Vuex实例的count:{{this.$store.state.count}}
        <br/>
        <button @click="increment">加一</button>
    </div>
</template>

<script>
    export default {
        name: "ModulesDemo",
        methods: {
            increment() {
                this.$store.commit('a/increment')
            }
        },
    }
</script>

通过添加{root: true}在全局命名空间中调度Action或提交mutation

// store/modules/moduleB.js
export default {
    namespaced: true,

    state: {
        count: 20,
    },
    mutations: {
        increment(state) {
            state.count++
        }
    },
    actions: {
        someAction({commit}) {
            commit('increment') // 触发模块B的increment
            // commit('increment', null, {root: true}) // 触发Vuex实例全局的increment
        },
    },
}
<template>
    <div>
        模块A的count:{{this.$store.state.a.count}}
        <br/>
        模块B的count:{{this.$store.state.b.count}}
        <br/>
        Vuex实例的count:{{this.$store.state.count}}
        <br/>
        <button @click="increment">加一</button>
    </div>
</template>

<script>
    export default {
        name: "ModulesDemo",
        methods: {
            increment() {
                this.$store.dispatch('b/someAction')
            }

        },
    }
</script>

使用mapStatemapGettersmapActions

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB,
  },
  state: {
    count: 1,
  },
  mutations: {
    increment(state) {
      state.count++
    },
})
// store/modules/moduleA.js
export default {
    namespaced: true,

    state: {
        count: 10,
    },
    mutations: {
        increment(state) {
            state.count++
        }
    },
    getters: {
        sumWithRootCount (state, getters, rootState) {
            return state.count + rootState.count
        },
    },
    actions: {
        incrementIfOddOnRootSum ({ state, commit, rootState }) {
            if ((state.count + rootState.count) % 2 === 1) {
                commit('increment')
                // commit('increment', null, {root: true})
            }
        }
    },
}
// store/modules/moduleB.js
export default {
    namespaced: true,

    state: {
        count: 20,
    },
    mutations: {
        increment(state) {
            state.count++
        }
    },
    actions: {
        someAction2: {
            root: true,
            handler({commit}) {
                // commit('increment')
                commit('increment', null, {root: true})
            }
        },
    },
}
<template>
    <div>
        模块A的count:{{a}}
        <br/>
        模块B的count:{{b}}
        <br/>
        Vuex实例的count:{{this.$store.state.count}}
        <br/>
        模块A的count+Vuex实例的count={{sumWithRootCount}}
        <br/>
        <button @click="incrementIfOddOnRootSum">加一</button>
    </div>
</template>

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

    export default {
        name: "ModulesDemo",
        computed: {
            ...mapState({
                a: state => state.a.count,
                b: state => state.b.count,
            }),
            ...mapGetters({
                sumWithRootCount: 'a/sumWithRootCount'
            })
        },
        methods: {
            ...mapActions({
                incrementIfOddOnRootSum: 'a/incrementIfOddOnRootSum'
            }),
        }
    }
</script>

参考:

posted @ 2021-02-03 11:21  gzhjj  阅读(89)  评论(0编辑  收藏  举报