Многомерные массивы, Vuex и мутации

Я пытаюсь как добавлять, так и удалять элементы в многомерном массиве, хранящемся во 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)
  }
}

person muffinlab    schedule 10.10.2018    source источник


Ответы (1)


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

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

1. Нормализуйте свои данные

This is an approach recommended by vue.js team member [here][2].

Если вы действительно хотите сохранить информацию об иерархической структуре после нормализации, вы можете использовать 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) или

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

...

Вы можете легко добиться этого с помощью другой библиотеки: объект-путь-неизменяемый. Например, предположим, что вы хотите добавить новую категорию в 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. Такой подход желателен, если вы не хотите нормализовать / денормализовать свои данные.

person b0nyb0y    schedule 11.10.2018
comment
Большое спасибо за этот ответ, это именно то, что мне было нужно. - person muffinlab; 11.10.2018
comment
@muffinlab Рад, что это помогло. :) - person b0nyb0y; 11.10.2018