为动态创建的组件分隔vuex存储 [英] Separating vuex stores for dynamically created components

查看:124
本文介绍了为动态创建的组件分隔vuex存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题让我陷入了一点困境。不幸的是,我在这里找不到答案(要求也没有帮助)。所以经过一些研究并在这里和那里询问后,似乎我得到了这个问题的解决方案。

This was the question got me stuck for a little bit. Unfortunately, I coudn't find answer here (asking also didn't help). So after doing some research and asking here and there, it seems that I got the solution to this issue.


如果您有一个问题,您已经知道了答案,并且您想要在公共场合记录这些知识,那么其他人
(包括你自己)可以在以后找到它。

If you have a question that you already know the answer to, and you would like to document that knowledge in public so that others (including yourself) can find it later.

当然,我的答案可能不是理想的,而且我知道它不是,这是我发布的关键点 - 改进它。

Of course, my answer may not be the ideal one, moreover I know it is not, that's the key point why I'm posting - to improve it.

注意,我没有在示例中使用动作。这个想法是一样的。

Note, I'm not using actions in example. The idea is the same.

让我们先从开始说明问题:

想象一下,我们有 App.vue ,它动态生成名为 Hello 的本地组件。

Imagine we have App.vue which dynamically generates its local component named 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

store.js

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

我们正在使用 v-for 通过遍历数组生成组件的指令 jobs 。我们的商店截至目前只包含一个空数组的
按钮应该做两件事:

We are using v-for directive to generate components by iterating through an array jobs. Our store as of now consists of only state with an empty array. Button New should do 2 things:

1)创建新的组件 Hello ,换句话说,将元素添加到 jobs (让它成为数字),这些将被指定为 id < hello> ,并通过本地组件为道具

1) create new component Hello, in other words add element to jobs (let it be numbers), which are going to be assigned as key and id of <hello>, and passed to local component as props.

2)生成本地商店 - 模块 - 保持任何数据作用于新创建的组件。

2) generate local stores - modules - to keep any data scoped to newly created components.

Hello.vue

Hello.vue

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

export default {
  props: ['id']
}

简单组件 - 输入一个按钮添加1.

Simple component - input with a button adding 1.

我们的目标是设计如下:

Our goal is to design something like this:

推荐答案

对于 NEW 按钮的第一次操作 - 生成组件 - 我们将变种添加到我们的 store.js

For the first operation of NEW button - generating components - we add mutation to our store.js

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

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

Second, creating local modules. Here we're going to use reusableModule to generated multiple instances of a module. That module we keep in separate file for convinience. Also, note use of function for declaring module state.

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

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

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

export default {
  state,
  getters,
  mutations
}

要使用 reusableModule ,我们会导入它并应用动态模块注册。

To use reusableModule we import it and apply dynamic module registration.

store.js

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 。我们可能需要 getters 突变操作来自 vuex 。要访问存储空间,我们需要创建 getters 。与突变相同

After, we're going to link Hello.vue with its storage. We may need state, getters, mutations, actions from vuex. To access storage we need to create our getters. Same with mutations.

Home.vue

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>

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

Imagine we have lots of getters, mutations and actions. Why not use {mapGetters} or {mapMutations}? When we have several modules and we know the path to module needed, we can do it. Unfortunately, we do not have access to module name.


代码在组件模块执行时运行(当你的app $ b $时b正在启动),而不是在创建组件时。所以这些助手只有在你提前知道模块名称时才能使用

The code is run when the component's module is executed (when your app is booting), not when the component is created. So these helpers can only be used if you know the module name ahead of time.

这里几乎没有帮助。我们可以将 getters 突变分开,然后将它们作为对象导入并保持清洁。

There is little help here. We can separate our getters and mutations and then import them as an object and keep it clean.

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

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

返回 App 组件。我们必须提交我们的变种,并为 App getter $ C>。为了说明我们如何访问模块中的数据。

Returning to App component. We have to commit our mutation and also let's create some getter for App. To show how can we access data located into modules.

store.js

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
    }
  } 
...

<$ c $中的完成代码c> App 组件

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

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

这篇关于为动态创建的组件分隔vuex存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆