一個簡單的實例演示vuex模塊化和命名空間

由於Vuex Store是全局註冊的,不利於較大的項目,引入模塊分離業務狀態和方法,引入命名空間解決不一樣模塊內(getters,mutaions,actions)名稱衝突的問題html

------------------------------------------------------------------vue

首先創建一個模塊 ./store/modules/sample.jsvuex

import SampleAPI from '@/api/sample-api-proxy.js'
import { _AjaxUrl } from '@/store/constants'

const state = {
    all: []
}
const mutations = {
    resolve (state, payload) {
        for (let item of payload) {
            state.all.push(item)
        }
    }
}
const getters = {
    allstr (state) {
        return state.join(',')
    }
}
const actions = {
    async init ({commit,state}, pid) {
        await SampleAPI.get(_AjaxUrl + '/api/game/all', params: {pid}).then((res) => {
            state.all = res.all
            commit('resolve', res.data)
        })
    }
}

export default {
    namespaced: true,
    state, mutations, getters, actions
}

./store/index.js 注入模塊api

import Vuex from 'vuex'
import sample_module from './modules/sample'
import other_module from './modules/other'

export default new Vuex.Store({
    //全局Store對象
    mutations,
    actions,
    state,

    //模塊
    modules: {         
        sample: sample_module,
        other: other_module
    }
})

啓動程序(main.js)中註冊 store 到根組件app

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

Vue.use(Vuex)
new Vue({
    el: '#app',
    data() {
        return { rootParam: 'test' }
    },
    store,
    router,
    template: '<Home/>',
    components: { Home }
})

頁面組件(./components/sample.vue)中聲明並調用ecmascript

<template>
    <div id="container">
    <ul class="sample-ul">
        <li v-for="(item, index) in all" :key="index">
            <span>{{item}}</span>
            <button @click="removeItem(index)">刪除</button>
        </li>
    </ul>
    <div>{{all2str}}</div>
    </div>
</template>

<style lang="stylus" rel="stylesheet/stylus" scoped>
@import '~style/common.styl'
nospace()
    margin 0
    padding 0
height(h)
    height unit(h, 'px')
    line-height unit(h, 'px')

.sample-ul
    list-style-type none
    @nospace
    li
        display block
        height(20)
    &:hover
        background-color #fcc
</style>

<script type="text/ecmascript-6">
import { createNamespacedHelpers, mapState } from 'vuex'
const { mapActions, mapGetters, mapMutations } = createNamespacedHelpers('sample')
const { mapActions: mapOtherActions, mapGetters: mapOtherGetters } = createNamespacedHelpers('other')

export default{
    data() {
      return {

      }
    },
    computed: {
        ...mapState({
            all : state => state.sample.all
        }),
        ...mapGetters(['all2str']),
        ...mapOtherGetters(['test'])
    },
    methods: {
        ...mapActions(['loadDataAsync']),
        ...mapMutations(['removeItem']),
        ...mapOtherMutations(['testing'])
    },
    created() {
        const pid = this.$route.query.pid
        this.loadDataAsync(keep, pid)
    }
}
</script>

推薦使用對象展開運算符將 mapMutations,mapGetters,mapActions,mapState 混入到頁面組件,頁面僅用於交互體驗,不要參雜過多的業務邏輯和狀態
經過 createNamespacedHelpers 映射到命名空間async

項目結構:this

├── index.html
├── main.js
├── api
│   ├── sample-api-proxy.js
│   └── ...
├── components
│   ├── sample.vue
│   └── ...
└── store
    ├── index.js
    ├── actions.js
    ├── mutations.js
    ├── state.js
    └── modules
        ├── sample.js
        └── other.js
相關文章
相關標籤/搜索