Ответы пользователя по тегу Vue.js
  • Можли ли продолжить всплытие собственных событий в vue.js?

    mrswylet
    @mrswylet Автор вопроса
    Если кто-то пришел сюда со страницы поисковика, то вот готовый ответ. (Текста будет много)
    (Скажу сразу, я нет могу гарантировать, что все написанной мной абсолютная истина, но код рабочий)
    Есть для варианта пробросить шину событий (event bus). У каждого есть плюсы и минусы. Сейчас рассмотрим оба.

    1. Проброс event bus через корневой компонент $root.
    Vue.component('mian-container', {
    	template: `<main-header ></main-header>`,
    	data(){ 
    		return{ 
    			name: 'я <<main-header></<main-header>' 
    		} 
    	},
    	// тут мы при создании компонента подписываем его на прослушку события 'selected-menu'
    	created(){ 
    		this.$root.$on('selected-menu', function (event) { 
    			console.log(event.target + this.name) 
    		}.bind(this)) // не забыть про .bind(this), иначе произойдет потеря контекста
    	} 
    })
    Vue.component('main-header', {
    	template: `<main-menu ></main-menu>`,
    	data(){ 
    		return{ 
    			name: 'я <main-menu></main-menu>' 
    		} 
    	},
    	// тут мы при создании компонента подписываем его на прослушку события 'selected-menu'
    	created(){ 
    		this.$root.$on('selected-menu', function (event) { 
    			console.log(event.target + this.name)  
    		}.bind(this)) // не забыть про .bind(this), иначе произойдет потеря контекста
    	}
    })
    Vue.component('main-menu', {
    	template: `<button @click="selectedMenu">Меню</button>`,
    	methods:{
    		selectedMenu(event){
    			// тут мы создаем событие 
    			this.$root.$emit('selected-menu', event)
    		}
    	}
    })
    new Vue({
    	el: '#main'
    })


    1. Проброс event bus через дополнительный экземпляр Vue, например bus.
    // тут создаем дополнительный экземпляр Vue, 
    // далее по коду используем его вместо 'this.$root'
    let bus = new Vue();
    
    Vue.component('mian-container', {
    	template: `<main-header ></main-header>`,
    	data(){ 
    		return{ 
    			name: 'я <<main-header></<main-header>' 
    		} 
    	},
    	created(){ 
    		bus.$on('selected-menu', function (event) { 
    			console.log(event.target + this.name) 
    		}.bind(this))
    	} 
    })
    Vue.component('main-header', {
    	template: `<main-menu ></main-menu>`,
    	data(){ 
    		return{ 
    			name: 'я <main-menu></main-menu>' 
    		} 
    	},
    	created(){ 
    		bus.$on('selected-menu', function (event) { 
    			console.log(event.target + this.name)  
    		}.bind(this))
    	}
    })
    Vue.component('main-menu', {
    	template: `<button @click="selectedMenu">Меню</button>`,
    	methods:{
    		selectedMenu(event){
    			bus.$emit('selected-menu', event)
    		}
    	}
    })
    new Vue({
    	el: '#main'
    })


    Какой вариант выбрать, решать конечно же вам. От себя могу добить следующее:
    1) способ через корневой компонент $root
    (+) более лаконичный, если вы работаете с системами сборки, например webpack, то вам не придется думать о подключении дополнительного экземпляра Vue в каждый файл
    (-) если у вам очень много "глобальных" событий, то будут проблемы с производительность

    2) способ через дополнительный экземпляр Vue
    (+) этот вариант менее чувствительный к большему количеству событий
    (-) если вы работаете с системами сборки, например webpack, то вам придется помнить о подключении дополнительного экземпляра Vue в каждый файл где вы будете использовать event bus
    Ответ написан