Многомерные массивы, Vuex и мутации - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь как добавить, так и удалить элементы в многомерном массиве, хранящемся в Vuex.

Массив представляет собой группу категорий, и каждая категория имеет подкатегорию (бесконечность, а не просто двумерный массив).

Пример набора данных выглядит примерно так:

[
   {
     id: 123,
     name: 'technology',
     parent_id: null,
     children: [
          id: 456,
          name: 'languages',
          parent_id: 123,
          children: [
             {
                id:789,
                name: 'javascript',
                parent_id: 456
             }, {
                id:987,
                name: 'php',
                parent_id: 456
             }
          ]
        }, {
          id: 333,
          name: 'frameworks', 
          parent_id 123,
          children: [
             {
                id:777,
                name: 'quasar',
                parent_id: 333
             }
          ]
        }
     ]
   }
]

.... мой вопрос: как мне лучше всего добавлять и удалять элементы в этом массиве, который находится внутри Vuex Store?

Обычно я манипулирую простыми массивами внутри Vuex Store, используя Vue.Set () для получения реактивности.Однако, поскольку я не уверен, насколько глубоко манипулирует вложенный массив - я просто не могу понять это.

Вот пример того, как я думал, что могу добавить элемент подкатегории, используя рекурсию:

export const append = (state, item) => {
  if (item.parent_uid !== null) {
    var categories = []
    state.data.filter(function f (o) {
      if (o.uid === item.parent_uid) {
        console.log('found it')
        o.push(item)
        return o
      }
      if (o.children) {
        return (o.children = o.children.filter(f)).length
      }
    })
  } else {
    state.data.push(item)
  }
}

1 Ответ

0 голосов
/ 11 октября 2018

Первое, что нужно понять, это то, что vuex или любая другая библиотека управления состоянием, основанная на архитектуре flux, не предназначена для обработки вложенных графов объектов, не говоря уже о произвольных / бесконечных вложенных объектах, которые вы упомянули.Что еще хуже, даже с мелким объектом состояния, vuex работает лучше всего, когда вы определяете форму состояния (все необходимые поля) заранее .

ИМХО, есть два возможныхподходы вы можете предпринять

1.Нормализовать ваши данные

Этот подход рекомендован членом команды vue.js здесь .

Если вы действительно хотите сохранить информацию об иерархической структуре после нормализации, вы можетеиспользуйте flat в сочетании с функцией преобразования для выравнивания вложенного объекта с помощью name примерно так:

const store = new Vuex.Store({
  ...
  state: {
    data: {
      'technology':                      { id: 123, name: 'technology', parent_id: null },
      'technology.languages':            { id: 456, name: 'languages', parent_id: 123 },
      'technology.languages.javascript': { id: 789, name: 'javascript', parent_id: 456 },
      'technology.languages.php':        { id: 987, name: 'php', parent_id: 456 },
      'technology.frameworks':           { id: 333, name: 'frameworks', parent_id: 123 },
      'technology.frameworks.quasar':    { id: 777, name: 'quasar', parent_id: 333 },
    }
  },
});

Затем вы можете использовать Vue.set() для каждого элемента в state.data как обычно.

2.Создайте совершенно новый объект состояния при модификации

Это второй подход, упомянутый в документации vuex:

При добавлении новых свойств в объект вы должны либо:

  • Используйте Vue.set(obj, 'newProp', 123) или

  • Замените этот объект на новый

    ...

Этого легко добиться с помощью другой библиотеки: object-path-immutable .Например, предположим, что вы хотите добавить новую категорию в languages, вы можете создать мутацию следующим образом:

const store = new Vuex.Store({
  mutations: {
    addCategory(state, { name, id, parent_id }) {
      state.data = immutable.push(state.data, '0.children.0.children', { id, name, parent_id });
    },
  },
  ...
});

Переназначая state.data новому объекту каждый раз, когда производится модификация, vuex Система реактивности будет должным образом проинформирована об изменениях, внесенных вами в state.data.Этот подход желателен, если вы не хотите нормализовать / денормализовать ваши данные.

...