【问题标题】:Array of objects - correct way of updating an object within the Vue.js ecosystem对象数组 - 在 Vue.js 生态系统中更新对象的正确方法
【发布时间】:2018-09-01 21:27:37
【问题描述】:

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

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

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);
    }
  }
})

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

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

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

失败的线是:

state.contentBlocks[contentBlock.id] = contentBlock

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

更新

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

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。

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

state.contentBlocks.splice(index, 1)

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

【问题讨论】:

    标签: javascript vue.js vuex


    【解决方案1】:

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

    See #2 of Why isn’t the DOM updating?

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

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

    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)
    

    【讨论】:

    • 我遇到了一些非常奇怪的行为......我什至不知道如何解释它。我有三个块,0、1、2。我删除了0。块1和2保留,但它们包含0和1的内容值???
    • state.contentBlocks.splice(index, 1, contentBlock) 似乎不想从数组中拼接contentBlock...
    • 更新有效 - 所以这也是公认的答案。
    • @alexdykyi 请停止投票 DigitalDrifters 回答!该方法有效,并且我正在存储一个对象数组,所以我当然需要一个数组!
    猜你喜欢
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 2021-09-14
    • 2020-11-11
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    相关资源
    最近更新 更多