Как правильно обновлять массив объектов родительского компонента из дочернего компонента? - PullRequest
0 голосов
/ 03 июня 2019

У меня сложная форма с разными вкладками. Я использую vue-router для переключения между ними и отображения различных модульных компонентов в router-view для каждого из них. На этих вкладках у меня есть дочерние компоненты с иногда другими вложенными дочерними компонентами. Я использую event bus подход для передачи данных из этих дочерних компонентов в дерево. Я делаю это, потому что последняя вкладка будет сводкой формы, и мне понадобится доступ ко всем данным формы. На данный момент я использую что-то вроде ниже.

Например, используя эту структуру:

|App
--|Start
--|Question 1
  --|Answer 1
  --|Answer 2
--|Question 2
...

В корневом компоненте (приложение):

data() {
  return {
    questions: 0,
    answers: []
  }
},
created() {
    eventBus.$on('answer-added', answer => {
        let answer_exists = false
        this.answers.forEach( (e, i) => {
            if(e.id == answer.answer_id) answer_exists = true
        });
        if(!answer_exists) this.answers.push({
            id: answer.answer_id,
            answer: answer.answer_text
        })
    });
}

Как правильно создавать / обновлять / удалять массив ответов в компоненте приложения каждый раз, когда происходит событие от дочернего элемента? Я уверен, что должен быть намного лучший способ, чем перебирать элементы массива, чтобы проверить, существует ли уже ответ или нет ... Просто не могу понять это.

Ответы [ 4 ]

0 голосов
/ 04 июня 2019

Передача обратного вызова от родителя к ребенку. Теперь они могут общаться снизу вверх. Дочерний элемент может передать любые данные, которые могут понадобиться родителю, а затем родитель может вернуть контроль и использовать свое состояние или состояние закрытия.

0 голосов
/ 03 июня 2019

То, что вы делаете, более или менее правильно.Там нет выхода из цикла.Тем не менее, есть определенные вещи, которые вы можете улучшить.Вместо forEach вы можете использовать Array.some метод .В качестве альтернативы вы можете использовать метод Array.find:

eventBus.$on('answer-added', answer => {

    // Instead of using forEach, you can use Array.some() method
    const answerExists = this.answers.some((x) => e.id == answer.answer_id);

    if (!answerExists) {
      this.answers.push({
        id: answer.answer_id,
        answer: answer.answer_text
      });
    }
});

Во-вторых, нет проблем с использованием шины событий , но обычно она используется для братьев или сестер-компонентное общение.Когда все компоненты находятся в одной и той же иерархии предков или родителей, правильное использование $emit для событий.

В вашем случае, даже если у вас есть иерархия вложенных компонентов, по мере развития приложенияиерархия может стать очень глубокой, и вы быстро потеряете привычный механизм publish-subscribe шины событий.Даже если это означает переиздание одних и тех же событий из промежуточных компонентов, вы должны следовать этой практике.

0 голосов
/ 04 июня 2019

Для тех, кто сталкивается с той же проблемой, проблема, с которой я столкнулся, решается с помощью Simple Global Store .Другие более сложные сценарии могут потребовать Vuex , как предложено @Dan выше.

0 голосов
/ 03 июня 2019

Вы имеете в виду что-то вроде:

if (!this.answers.find(a => a.id === answer.answer_id)) {
    this.answers.push(/* ... */);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...