2017-06-03 253 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>