【问题标题】:How to create isolated Vuex states for every initialized instance of a component in Vue?如何为 Vue 中组件的每个初始化实例创建隔离的 Vuex 状态?
【发布时间】:2022-01-06 13:55:16
【问题描述】:

我是 Vue 的新手。

我看到有人建议我们需要为组件使用 Vuex 模块来存储它们的状态数据,以便我们可以在父组件中访问该数据。

例如,我有 MarkdownEditor.vue 组件,我需要从父组件访问它的数据。我将状态存储在 Vuex 模块中,例如 markdownEditorStore.js... 我可以在父组件中轻松访问此状态,例如 this.$store.state.markdownEditor.XYZ

没关系。但是,如果我有 n 个 MarkdownEditor 组件并且每个组件都需要隔离状态怎么办?这是一个非常基本的问题,但是我该如何处理呢?

我需要基于模块实例的解决方案,而不是基于模块的解决方案。

【问题讨论】:

  • 您需要以某种方式识别实例。状态数组或某种形式的 uid 中的索引。这可能是 XY 问题,人们可以提出任何建议,但这并不意味着它适合您的情况。如果有直接的父子关系并且数据没有在其他任何地方使用,那么像往常一样使用 Vue 事件会更直接
  • @EstusFlask 假设我在其 created() 方法中为子组件的每个实例创建了一个 UUID。如何在父组件中访问该子组件的 UUID 以从 vuex 状态获取子组件的数据?获取实例的 UUID 的唯一方法是在父组件中启动该组件时创建并传递 UUID?这对我来说看起来很脏。 UUID 生成可能在孩子的代码 imo 中,但不知道如何。那么在那种情况下我怎么能得到那个 UUID 呢?问题...但不知道答案。
  • 这将违背初衷。如果您能够将 id 从孩子传递给父母,那么您也可以传递其余数据。由于您已经绑定到商店,您可以让它保存 id 的逻辑,即具有 getEditorId getter 函数。让它action 不好,afaik 动作可以返回随机数据,但它总是用承诺包装,我不确定它是否允许。
  • 即在您的情况下,它将是 this.childEditorId = store.getters.getEditorId(); store.dispatch('createEditor', this.childEditorId)this.childEditorId = await store.dispatch('createEditor'),第一种方法不那么简单但更传统

标签: javascript vue.js vuex


【解决方案1】:

模块功能是在不同域之间拆分逻辑(您的情况下的编辑器是一个模块)。不适用于实例本身。

经验法则是,将与 Vuex 存储连接的父级将加载所需的数据传递给 MarkdownEditor.vue。理想情况下,MarkdownEditor 能够仅使用从父级接收到的道具进行加载。这是将视觉与状态分开的好习惯。更容易测试和清晰的组件 API。

即使您有 N 个可能的 ME(MarkdownEditor) 实例,您也可以一次显示一个或多个。对于这两种情况,您都可以使用 MarkdownEditorDataStore 来保存所需的所有数据。

然后您只需要访问每个 ME 实例的正确数据。这取决于您的商店和组件结构。我能想到的两种方法是,要么你有一个用于 N ME 实例的数组,比如editors: [ { id: 1, title: X}, { id: 2, title: Y } ],要么是一个包含所有数据的对象{ editors: { 1: {id: 1, title: X }, 2: { id: 2, title: Y } }

您可以通过this.$store.state.MarkdownEditorDataStore.editors[myID] 获取数据 或者 this.$store.state.MarkdownEditorDataStore.editors.find(id => myID === id)

您可以拥有一个包含currentEditorId 的数据属性,以防您一次只显示一个实例。在这种情况下使用 getter 来显示 actualCurrentEditorObject 会更好。

【讨论】:

  • 感谢您的回答。很明显,你让我完全正确。那么完成这种“ID”方式的唯一方法是在父组件中创建该ID并将其传递给子组件?我们是否可以将生成子组件 ID 的代码移到子组件本身并仍然在父组件中访问它?
  • 实现目标的方法不止一种,这取决于您以及实现目标所需的条件。 ID 可以在添加新编辑器时创建,并且您分配该 ID,不一定在组件中,例如,它是否也可以通过操作在商店中。在我看来,您需要弄清楚将状态逻辑与组件逻辑分开的位置。组件本身不需要创建 ID,除非它对这个组件有意义。但是这里的 ID 似乎很有价值,只是为了跟踪您的实例,然后对商店更有价值。
  • 好的,谢谢,这帮助我克服了困惑
【解决方案2】:

我从您的问题中了解到,您希望每个组件都有一个单独的状态,您可以通过使用 namespace=true 创建一个单独的模块来实现 对于每个组件 https://vuex.vuejs.org/guide/modules.html#namespacing

【讨论】:

  • 实际上不是。命名空间是一个模块级的解决方案。我在询问实例级解决方案(例如,模块的启动实例,或组件/其状态的每个实例的单独状态)。谢谢顺便说一句。
  • @oyrinkozhi 您可以为每个实例动态创建一个模块。如果可行,取决于状态的复杂性。
猜你喜欢
  • 2018-06-30
  • 1970-01-01
  • 2020-06-21
  • 2020-02-18
  • 2020-02-05
  • 2023-03-11
  • 2019-10-30
  • 2017-11-04
  • 1970-01-01
相关资源
最近更新 更多