对象数组 - 更新Vue.js生态系统中对象的正确方法

问题描述 投票:1回答:1

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

我正在使用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实例的日志:

console.log(this.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左侧的contentBlocks。然而他们来自0和1的内容???

javascript vue.js vuex
1个回答
2
投票

这是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)
© www.soinside.com 2019 - 2024. All rights reserved.