2017-06-03 273 views
9

這就是讓我卡住了一點的問題。不幸的是,我在這裏找不到答案(問也沒有幫助)。所以在做了一些研究並問到這裏後,似乎我得到了解決這個問題的方法。爲動態創建的組件分隔vuex存儲

如果你已經知道答案的一個問題,你 想記錄在公共知識,讓其他人 (包括自己)以後可以找到它。

當然,我的回答可能不是理想的,而且我知道它不是,這是我發佈的關鍵點 - 改進它。

請注意,我沒有在示例中使用動作。這個想法是一樣的。

讓我們陳述問題開始:

試想一下,我們有App.vue其中動態生成的本地組件命名Hello

<template> 
    <div id="app"> 
    <div> 
     <hello v-for="i in jobs" :key="i" :id="i"></hello> 
     <button @click="addJob">New</button> 
    </div> 
    </div> 
</template> 

<script> 
import Hello from './components/Hello' 

export default { 
    components: { 
    Hello 
    }... 

store.js

export const store = new Vuex.Store({ 
    state: { 
    jobs: [] 
    } 
}) 

我們正在使用v-for指令由通過陣列jobs迭代以產生組件。截至目前,我們的store僅包含空數組state。 按鈕New應該做兩兩件事:1)創建新的組件Hello,換句話說,添加元素jobs(讓它爲數字),這是將被指定爲key<hello>id,並傳遞到本地組件作爲props2)生成本地商店 - 模塊 - 保留任何數據範圍到新創建的組件。

Hello.vue

<template> 
    <div> 
    <input type="number" :value="count"> 
    <button @click="updateCountPlus">+1</button> 
    </div> 
</template> 

export default { 
    props: ['id'] 
} 

簡單的組件 - 輸入一個按鈕加1

我們的目標是設計出這樣的事情: Vuex local stores

回答

9

對於NEW按鈕的第一操作 - 生成組件 - 我們添加mutation我們store.js

mutations: { 
    addJob (state) { 
     state.jobs.push(state.jobs.length + 1) 
... 
} 

其次,創建本地模塊。這裏我們將使用reusableModule來生成一個模塊的多個實例。爲了方便,我們將這個模塊保存在單獨的文件中。另外,請注意使用函數聲明模塊狀態

const state =() => { 
    return { 
    count: 0 
    } 
} 

const getters = { 
    count: (state) => state.count 
} 

const mutations = { 
    updateCountPlus (state) { 
    state.count++ 
    } 
} 

export default { 
    state, 
    getters, 
    mutations 
} 

要使用reusableModule我們導入它並應用動態模塊註冊。

store.js

import module from './reusableModule' 

const {state: stateModule, getters, mutations} = module 

export const store = new Vuex.Store({ 
    state: { 
    jobs: [] 
    }, 
    mutations: { 
    addJob (state) { 
     state.jobs.push(state.jobs.length + 1) 
     store.registerModule(`module${state.jobs.length}`, { 
     state: stateModule, 
     getters, 
     mutations, 
     namespaced: true // making our module reusable 
     }) 
    } 
    } 
}) 

後,我們將其存儲鏈接Hello.vue。我們可能需要state,getters,mutations,actionsvuex。要訪問存儲,我們需要創建我們的getters。與mutations相同。

Home.vue

<script> 

export default { 
    props: ['id'], 
    computed: { 
    count() { 
     return this.$store.getters[`module${this.id}/count`] 
    } 
    }, 
    methods: { 
    updateCountPlus() { 
     this.$store.commit(`module${this.id}/updateCountPlus`) 
    } 
    } 
} 
</script> 

假設我們有很多gettersmutationsactions。爲什麼不使用{mapGetters}{mapMutations}?當我們有幾個模塊,並且我們知道需要模塊的路徑時,我們可以做到。不幸的是,我們無法訪問模塊名稱。

代碼在組件的模塊執行時(當您的應用程序 引導時)運行,而不是在組件創建時運行。因此,只有在您知道模塊名稱之前,才能使用這些幫助程序 。

這裏沒有什麼幫助。我們可以分開我們的gettersmutations,然後將它們作爲對象導入並保持清潔。

<script> 
import computed from '../store/moduleGetters' 
import methods from '../store/moduleMutations' 

export default { 
    props: ['id'], 
    computed, 
    methods 
} 
</script> 

返回到App組件。我們必須承諾我們的mutation,並讓我們爲App創建一些getter。展示如何訪問位於模塊中的數據。

store.js

export const store = new Vuex.Store({ 
    state: { 
    jobs: [] 
    }, 
    getters: { 
    jobs: state => state.jobs, 
    sumAll (state, getters) { 
     let s = 0 
     for (let i = 1; i <= state.jobs.length; i++) { 
     s += getters[`module${i}/count`] 
     } 
     return s 
    } 
    } 
... 

App部件精加工代碼

<script> 
import Hello from './components/Hello' 
import {mapMutations, mapGetters} from 'vuex' 

    export default { 
     components: { 
     Hello 
     }, 
     computed: { 
     ...mapGetters([ 
      'jobs', 
      'sumAll' 
     ]) 
     }, 
     methods: { 
     ...mapMutations([ 
      'addJob' 
     ]) 
     } 
    } 
    </script>