Взаимодействие между сестринскими компонентами. Шина событий

Последнее обновление: 30.01.2018

Во Vue.js также можно организовать взаимодействие между компонентами, которые находятся на одном уровне, то есть являются сестринскими.

В этом случае взаимодействие происходит через родительский компонент. Например, определим два дочерних компонента, которые взаимодействуют через родительский компонент:

<!DOCTYPE html>
<html>
<head>
<title>Компоненты Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
	<h2>User</h2>
	<useredit :name="user" @userchange="change"></useredit>
	<userinfo :name="user" @userreset="reset"></userinfo>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script>
Vue.component('useredit', { 
	props: ["name"],
	template: '<div><input v-model="name" /><button @click="save">Save</button></div>',
	methods:{
		save(){
			this.$emit("userchange", this.name);
		}
	}
});
Vue.component('userinfo', { 
	props: ["name"],
	template: `<div><p>Имя: {{name}}</p><button @click="reset">Reset</button></div>`,
	methods:{
		reset(){
			this.$emit("userreset");
		}
	}
});
new Vue({
    el: "#app",
	data:{
		user:'Tom'
	},
	methods:{
		change(name){
			this.user = name;
		},
		reset(){
			this.user = 'Tom';
		},
	}
});
</script>
</body>
</html>

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

Сестринские компоненты во Vue.js

Шина событий

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

var eventBus = new Vue();

В компоненте, который хочет изменить данные, мы вызываем через эту шину событие:

eventBus.$emit("событие", данные);

А в другом компоненте в методе created устанавливаем обработчик этого события:

created(){
	eventBus.$on("событие", (данные)=>{
		// действия
	});
}

Например, рассмотрим следующий пример:

<!DOCTYPE html>
<html>
<head>
<title>Компоненты Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
	<h2>User</h2>
	<useredit :user="user"></useredit>
	<userinfo :user="user"></userinfo>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script>
var eventBus = new Vue();

Vue.component('useredit', { 
	props: ["user"],
	template: `<div>
					<input v-model="userName" />
					<button @click="save">Save</button>
				</div>`,
	data: function () {
      return { userName: this.user}
    },
	methods:{
		save(){
			eventBus.$emit("userchange", this.userName);
		}
	}
});
Vue.component('userinfo', { 
	props: ["user"],
	template: '<div><p>Имя: {{userName}}</p></div>',
	data: function () {
      return { userName: this.user}
    },
	created(){
		eventBus.$on("userchange", (name)=>{
			this.userName = name;
		});
	}
});
new Vue({
    el: "#app",
	data:{
		user:'Tom'
	}
});
</script>
</body>
</html>

Здесь объект Vue не обрабатывает никаких событий и просто передает в компоненты имя пользователя. В самих компонентах привяка идет не к свойству из props, а к свойству из параметра data. То есть в данном случае даже если бы мы, как в предыдущем примере, захотели бы изменить значения свойств через обработку событий в объекте Vue, то мы бы не смогли бы это сделать. Однако благодаря шине событий мы все же это можем сделать. Компонент useredit вызывает через шину событий событие userchange, а второй компонент - userinfo обрабатывает это событие.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850