Массив объектов - правильный способ обновления объекта в экосистеме Vue.js - PullRequest
0 голосов
/ 02 сентября 2018

Я не уверен, в чем конкретно заключается проблема, но я собираюсь выяснить, может ли кто-нибудь помочь мне понять, что происходит с моим кодом.

Я пользуюсь магазином 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)
}

в моем магазине. Тем не менее, это не удаляет блоки содержимого.

Я попытался изменить предложенный код на:

state.contentBlocks.splice(index, 1)

Но это вызывает странное поведение. Например, у меня есть блоки индексов 0, 1 и 2 ... Я изменяю, чтобы удалить индекс 0. Все выглядит хорошо - у меня есть только contentBlocks с индексами 1 и 2 слева. Все же они приходят с содержанием от 0 и 1 ???

1 Ответ

0 голосов
/ 02 сентября 2018

Это ограничение реактивности Vue относительно массивов.

См. № 2 раздела Почему не обновление DOM?

Когда вы изменяете массив, напрямую устанавливая индекс (например, arr[0] = val) или изменяя его свойство длины. Точно так же Vue.js не может получить эти изменения. Всегда изменяйте массивы с помощью метода экземпляра Array или полностью его заменяя. Vue предоставляет удобный метод arr.$set(index, value), который является синтаксическим сахаром для arr.splice(index, 1, value)

Вы можете решить эту проблему, используя Vue.set или Array.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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...