对象数组 - 在 Vue.js 生态系统中更新对象的正确方法 [英] Array of objects - correct way of updating an object within the Vue.js ecosystem

查看:22
本文介绍了对象数组 - 在 Vue.js 生态系统中更新对象的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定问题到底出在哪里,但我会看看是否有人可以帮助我了解我的代码出了什么问题.

I'm not sure exactly where the issue lies with this, but I'm going to see if anyone can help me understand what is going wrong with my code.

我正在使用 Vuex 存储来跟踪一些不断变化的状态.我这样做如下:

I am utilising the Vuex store, to keep a track of some state that is constantly mutating. I'm doing this as follows:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    id: 0,
    contentBlocks: []
  },
  mutations: {
    addContentBlock(state, contentBlock) {
      contentBlock.id = state.id
      state.contentBlocks.push(contentBlock)
      state.id += 1
    },
    updateContentBlock(state, contentBlock) {
      state.contentBlocks[contentBlock.id] = contentBlock
    },
    removeContentBlock(state, contentBlock) {
      state.contentBlocks.splice(state.contentBlocks.indexOf(contentBlock), 1);
    }
  }
})

创建和删除块似乎工作正常.

Creating and deleting blocks seems to work fine.

但是,在更新块时 - 出了点问题.我可以通过显示 contentBlocks 实例的日志来解释出了什么问题的唯一方法:

However, when updating a block - something is going wrong. The only way I can explain what is going wrong is by showing the log of the contentBlocks instance:

在上面的截图中可以看到,已经更新的对象实例(上面例子中的索引1)不太正确,它似乎不是一个观察者对象?

As you can see in the above screenshot, the object instances that has been updated (index 1 in the above example) is not quite correct, it doesn't seem to be an Observer object?

失败的一行是:

state.contentBlocks[contentBlock.id] = contentBlock

所以,我想知道......这应该是什么?

So, I'm wondering...what should this be?

更新:

根据以下答案的建议,我有以下几点:

On the advise of the below answer I have the following:

updateContentBlock(state, contentBlock) {
  const index = state.contentBlocks.findIndex(block => block.id === contentBlock.id)
  Vue.set(state.contentBlocks, index, contentBlock)
},
removeContentBlock(state, contentBlock) {
  const index = state.contentBlocks.findIndex(block => block.id === contentBlock.id)
  state.contentBlocks.splice(index, 1, contentBlock)
}

在我的店里.但是,这不会删除 contentBlocks.

in my store. However, this isn't removing contentBlocks.

我已尝试将建议的代码更改为:

I've tried changing the suggested code to:

state.contentBlocks.splice(index, 1)

但这会导致一些奇怪的行为.例如,我有索引 0、1 和 2 的块……我变异以删除索引 0.一切看起来都不错 - 我只剩下索引 1 和 2 处的 contentBlocks.然而它们带有来自 0 和 1 的内容???

But this is causing some odd behaviour. For example, I have blocks of indices 0, 1 and 2 ... I mutate to remove index 0. All looks good - I have only the contentBlocks at indices 1 and 2 left. Yet they come with the content from 0 and 1 ???

推荐答案

这是 Vue 对数组的反应性的限制.

This is a limitation of Vue's reactivity regarding arrays.

见#2 of 为什么 DOM 没有更新?

当您通过直接设置索引(例如 arr[0] = val)或修改其长度属性来修改数组时.类似地,Vue.js 无法获取这些更改.始终使用 Array 实例方法修改数组,或完全替换它.Vue 提供了一个方便的方法 arr.$set(index, value),它是 arr.splice(index, 1, value)

When you modify an Array by directly setting an index (e.g. arr[0] = val) or modifying its length property. Similarly, Vue.js cannot pickup these changes. Always modify arrays by using an Array instance method, or replacing it entirely. Vue provides a convenience method arr.$set(index, value) which is syntax sugar for arr.splice(index, 1, value)

您可以通过在模块中使用 Vue.setArray.splice 来解决此问题:

You can solve this by using Vue.set or Array.splice in your module:

import Vue from 'vue'

// find the block's index in the array
const index = state.contentBlocks.findIndex(block => block.id === contentBlock.id)

// using Vue.set
Vue.set(state.contentBlocks, index, contentBlock)

// using Array.splice
state.contentBlocks.splice(index, 1, contentBlock)

这篇关于对象数组 - 在 Vue.js 生态系统中更新对象的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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