【问题标题】:How to push to js array with a key while remaining reactive in Vue.js?如何在 Vue.js 中保持反应性的同时用键推送到 js 数组?
【发布时间】:2019-11-20 07:19:54
【问题描述】:

如果我的状态中有一个数组:

  state: {
    users: []
  },

我有这样的对象:

{
  id: 1,
  name: "some cool name"
}

我将它们添加到像users.push(user); 这样的mutator 中。如何将它添加到 users 数组中,而不是 0:{...} 它最终使用真正的 id 作为键 1:{...}

我知道我可以做类似users[user.id] = user 的事情,但我认为这不会在Vue.js 中起反应

【问题讨论】:

  • 我不了解 vue,但在使用 redux 时,一个常见的模式是将用户更改为一个对象,然后拥有一个仅包含 id 的数组。 state: { users: { byId: {}, allIds: [] } } 这样您就可以循环/映射 allIds 数组并将其与相应的 byId 对象匹配。

标签: javascript arrays vue.js key vuex


【解决方案1】:

如果您想通过 id 查找数组,则可能是错误的数据结构。更有可能你想要一个对象,users: {}。只有在 id 之间的间隔相对较少时,数组才是真正合适的。

要使值保持反应性,您可以使用Vue.sethttps://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats。因此,使用您的示例将是:

Vue.set(users, user.id, user)

如果您决定坚持使用数组,那么还有其他选择,https://vuejs.org/v2/guide/list.html#Caveats,例如 splice

在 Vuex 中规范化数据的相关阅读:https://forum.vuejs.org/t/vuex-best-practices-for-complex-objects/10143

更新:

根据您关于需要基于键的查找和过滤的 cmets,我的建议是使用对象存储值,然后在您需要数组时为 Object.values(users) 创建一个 getter 或计算属性。 getter 和计算属性都被缓存,因此开销(无论如何都非常小)只会在用户更改时产生。然后可以使用filter 过滤该数组。

【讨论】:

  • 谢谢。但是在更改为对象后,我不能再使用.filter,因为它不再是一个数组。根据我的测试,实现在对象上使用谓词的.filter 比在数组上慢一个数量级。
  • @ColtonScottie 使用 ids 作为键和过滤听起来像是一个奇怪的组合。如果您的“过滤”仅基于 id,那么您最好在 id 数组上使用 map
  • 不,过滤是针对每个对象内的值。在这里查看性能jsben.ch/FQHwP。我需要两者,因为索引将允许我使用 id 快速标准化链接到子对象,过滤是因为用户应该能够过滤不同的属性值。
  • @ColtonScottie 只有我原始答案的第一段涉及使用对象。其余部分也与数组有关,所以我相信它回答了您关于确保值是反应性的问题,无论您选择哪种结构。我现在已经对其进行了更新,以尝试解决您对使用对象的担忧,但我怀疑操作这些数据结构的性能与更新 DOM 的性能相比将是微不足道的。需要有大量的条目才能真正发挥作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
  • 2019-11-20
  • 2017-06-05
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
相关资源
最近更新 更多