为动态创建的组件分隔vuex存储

ogo*_*tos 25 javascript module store on-the-fly 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
  }...
Run Code Online (Sandbox Code Playgroud)

store.js

export const store = new Vuex.Store({
  state: {
    jobs: []
  }
})
Run Code Online (Sandbox Code Playgroud)

我们使用v-for指令通过遍历数组来生成组件jobs.我们store现在只state包含一个空数组.按钮New应该做两件事:

1)创建新的组件Hello,换句话说添加元素jobs(让它成为数),其中将要被分配为keyid<hello>,并传递到本地部件如props.

2)生成本地存储 - 模块 - 以保持任何数据作用于新创建的组件.

Hello.vue

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

export default {
  props: ['id']
}
Run Code Online (Sandbox Code Playgroud)

简单组件 - 使用添加1的按钮输入.

我们的目标是设计这样的东西: Vuex本地商店

ogo*_*tos 21

对于NEW按钮生成组件的第一个操作- 我们添加mutation到我们的store.js

 mutations: {
    addJob (state) {
      state.jobs.push(state.jobs.length + 1)
...
}
Run Code Online (Sandbox Code Playgroud)

第二,创建本地模块.这里我们将用于reusableModule生成模块的多个实例.该模块我们保存在单独的文件中以方便.另外,请注意使用函数来声明模块状态.

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

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

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

export default {
  state,
  getters,
  mutations
}
Run Code Online (Sandbox Code Playgroud)

要使用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
      })
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

之后,我们将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>
Run Code Online (Sandbox Code Playgroud)

想象一下,我们有很多getters,mutationsactions.为什么不使用{mapGetters}{mapMutations}?当我们有几个模块并且我们知道所需模块的路径时,我们就可以做到.不幸的是,我们无法访问模块名称.

代码在组件的模块执行时(应用程序启动时)运行,而不是在创建组件时运行.因此,只有在提前知道模块名称时才能使用这些助手.

这里几乎没有帮助.我们可以分开我们gettersmutations,然后导入它们作为一个对象,并保持清洁.

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

export default {
  props: ['id'],
  computed,
  methods
}
</script>
Run Code Online (Sandbox Code Playgroud)

回到App组件.我们有我们的承诺mutation,也让我们创造出一些getterApp.展示我们如何访问位于模块中的数据.

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
    }
  } 
...
Run Code Online (Sandbox Code Playgroud)

完成App组件中的代码

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

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