Испускание событий удаленному родственнику компонента [duplicate]

Это не отвечает на ваш вопрос сам по себе; он предлагает альтернативное решение, которое может повлиять на тот же результат.

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

Например, у вас может быть таблица, которая выглядит следующим образом.

CONDITION_ID | MINIMUM | MAXIMUM | IS_PRIME  |   ETC.
______________________________________________________
      1      |    2    |   NULL  |   NULL    |   ...
      2      |    4    |    6    |   NULL    |   ...

Эти записи строк, соответственно, соответствуют правилам value > 2 и 6 > value > 4.

Это дает ряд преимуществ по сравнению с вашим подходом.

  • Улучшенная производительность и чистота
  • Ваши условия могут быть оценены на уровне базы данных и могут использоваться для фильтрации запросов
  • . Вам не нужно беспокоиться о том, как обрабатывать сценарии, в которых синтаксис псевдокода
34
задан Bassem El Hachem 6 March 2017 в 00:45
поделиться

3 ответа

Сообщество Vue обычно предпочитает использовать Vuex для решения этой проблемы. Изменения приводятся к состоянию Vuex, и представление DOM просто вытекает из этого, устраняя необходимость в событиях во многих случаях.

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

Ниже приведен мой первоначальный ответ на этот вопрос, и это не тот подход, который я бы принял сейчас , имея больше опыта с Vue.


Это случай, когда я могу не согласиться с выбором дизайна Vue и прибегать к DOM.

В grand-child,

methods: {
    doEvent() { 
        try {
            this.$el.dispatchEvent(new Event("eventtriggered"));
        } catch (e) {
            // handle IE not supporting Event constructor
            var evt = document.createEvent("Event");
            evt.initEvent("eventtriggered", true, false);
            this.$el.dispatchEvent(evt);
        }
    }
}

и в parent,

mounted(){
    this.$el.addEventListener("eventtriggered", () => this.performAction())
}

В противном случае вы должны переизлучить или использовать шину.

Примечание: я добавил код в методе doEvent для обработки IE; этот код можно извлечь многоразовым способом.

18
ответ дан Bert 15 August 2018 в 21:28
поделиться
  • 1
    Это ведет себя по-разному для IE? не знал, что существуют расхождения в браузерах с vue ... – Bassem El Hachem 7 March 2017 в 23:39
  • 2
    @BassemLhm Vue отлично работает с IE. Проблема с IE не Vue, это решение DOM, и вы не можете делать новое событие () в IE. Вы должны document.createEvent (). При необходимости я могу добавить поддержку IE. – Bert 7 March 2017 в 23:45

Да, вы правильные события только от ребенка к родительскому. Они не идут дальше, например. от ребенка до дедушки и бабушки.

Документация Vue (кратко) рассматривает эту ситуацию в разделе Non Parent-Child Communication .

Общая идея заключается в том, что в компонент grandparent вы создаете пустой компонент Vue, который передается от дедушки и бабушки до детей и внуков через реквизит. Дедушка и бабушка прислушиваются к событиям, и внуки излучают события на этой «автобусе событий».

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

Вот пример , как реализовать простую глобальную шину событий .

15
ответ дан Sly_cardinal 15 August 2018 в 21:28
поделиться

Другое решение будет:

Использует vm.$root.$emit в grand-child, затем использует vm.$root.$on у предка (или где угодно).

Vue.component('parent', {
  template: '<div>I am the parent - {{ action }} <child @eventtriggered="performAction"></child></div>',
  data(){
    return {
      action: 'No action'
    }
  },
  created: function () {
  	this.$root.$on('eventtriggered1', () => {
    	this.performAction()
    })
  },
  methods: {
    performAction() { this.action = 'actionDone' }
  }
})

Vue.component('child', {
  template: '<div>I am the child <grand-child @eventtriggered="doEvent"></grand-child></div>',
  methods: {
    doEvent() { 
    	//this.$emit('eventtriggered') 
    }
  }
})

Vue.component('grand-child', {
  template: '<div>I am the grand-child <button @click="doEvent">Do Event</button></div>',
  methods: {
    doEvent() { this.$root.$emit('eventtriggered1') }
  }
})

new Vue({
  el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <parent></parent>
</div>

0
ответ дан Sphinx 15 August 2018 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: