Вопрос:

Как создавать события в цепочке подкомпонентов с помощью Vue js 2?

javascript vuejs2

10116 просмотра

4 ответа

1352 Репутация автора

У меня есть приложение VUE с использованием:

компонент-родительский компонент, который сделан из компонента-дочернего

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

Что я сделал до сих пор:

    var vm = new Vue({
        el: '#app',

        methods:{

            itemSelectedListener: function(item){
                console.log('itemSelectedListener', item);
            }
        }
    });




 Vue.component('component-child', {

                        template: ' <span  v-on:click="chooseItem(pty )" >Button  </span>'
                        ,
                        methods: {

                            chooseItem: function(pty){
                                console.log(pty);
                                this.$emit('itemSelected', {
                                    'priority' : pty
                                });
                            }
                        }
                    });

Vue.component('component-parent', {
                        template: '<component-child  v-for="q in items" ></component-child>'
                    });

HTML:

<component-parent v-on:itemSelected="itemSelectedListener"  ></component-parent>

Он достигает моего console.log (pty); строка, но кажется, что this. $ emit ('itemSelected' не пройдет:

console.log ('itemSelectedListener', item); // это не будет называться ...

намек?

я должен всплывать событие от child-> parent-> Vue-instance? (Я тоже пытался, но безуспешно)

Автор: koalaok Источник Размещён: 03.02.2017 04:51

Ответы (4)


14 плюса

1169 Репутация автора

У вашего component-parentшаблона есть одна проблема, так как он пытается отобразить несколько дочерних компонентов. Vue обычно требует одного корневого элемента div внутри компонентов, поэтому вам нужно обернуть его в тег div или другой тег.

<div>
    <component-child  v-for="q in items"></component-child>
</div>

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

Root //but you listen to the event up here 1 level above
 Component 1 //you should listen to the event here
  Component 2 //your try to emit it from here

У вас есть 2 варианта здесь. Либо излучайте, component-childслушайте это, даже component-parentпотом распространяйте это даже вверх. Скрипка https://jsfiddle.net/bjqwh74t/29/

Второй вариант - зарегистрировать глобальный так называемый busпустой экземпляр vue, который вы можете использовать в тех случаях, когда вы хотите установить связь между компонентами, не являющимися дочерними. Скрипка https://jsfiddle.net/bjqwh74t/30/

Обычно между родительским и дочерним компонентами вы используете события напрямую, передавая из дочернего и слушая в родительском v-on:event-name="handler"компоненте, но в тех случаях, когда у вас больше уровней между компонентами, вы используете второй подход.

Ссылка на документ для первого случая: https://vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events

Ссылка на документ для второго случая: https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

PS: предпочитайте использовать кебаб-кейс для названий событий, что означает, что вы пишете -вместо заглавных букв. Написание заглавными буквами может привести к странным ситуациям, когда ваше событие не попадает в корень.

Автор: Cristi Jora Размещён: 03.02.2017 08:02

1 плюс

18 Репутация автора

Уже немного поздно, но вот как я это сделал:

Компонент-ребенок:

this.$root.$emit('foobar',{...});

Компонент-родитель:

this.$root.$on('foobar')
Автор: behnam Tehrani Размещён: 15.06.2018 01:10

1 плюс

815 Репутация автора

В вашем дочернем компоненте просто используйте $emitдля отправки события $rootследующим образом:

v-on:click="$root.$emit('hamburger-click')"

Затем в родительском компоненте (например, «Приложение») настройте прослушиватель в mountedхуке жизненного цикла Vue следующим образом:

  export default {
    <snip...>
    mounted: function() {
      this.$root.$on('hamburger-click', function() {
        console.log(`Hamburger clicked!`);
      });
    }
  }
Автор: Geek Stocks Размещён: 10.08.2018 11:55

5 плюса

1691 Репутация автора

Для чего это стоит, вы можете использовать API событий браузера. Он требует немного больше сценариев, чем встроенный материал Vue, но он также помогает решить эти проблемы (и примерно столько же кода, сколько при создании "шины", как в принятом ответе).

На дочернем компоненте:

this.$el.dispatchEvent(new CustomEvent('itemSelected', { detail: { 'priority' : pty }, bubbles: true, composed: true });

На родительском компоненте, в mountedчасти жизненного цикла:

mounted() {
    this.$el.addListener('itemSelected', e => console.log('itemSelectedListener', e.detail));
}
Автор: codeMonkey Размещён: 14.12.2018 07:35
Вопросы из категории :
32x32