Создание событий

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

Через props мы можем передать данные от родительского компонента в дочерний. Но что если мы хотим также передавать данные и в обратном направлении: от дочернего компонента к родителю? В этом случае необходимо определить свои события. Дочерний компонент будет генерировать событие с помощью вызова this.$emit(имя_события), а родительский компонент будет отлавливать это событие с помощью установки атрибута v-on:название_события и при получении события поизводить определенные действия. Например:

<!DOCTYPE html>
<html>
<head>
<title>Компоненты Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
	<h2>Hello, {{name}}</h2>
    <useredit :user="name" v-on:userchange="change"></useredit>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script>
Vue.component('useredit', {
	props: ["user"],
	data: function () {
      return { userName: this.user}
    },
	template: '<div><input type="text" v-model="userName" v-on:input="onUserChange" /><p>Name: {{userName}}</p></div>',
	methods: {
		onUserChange: function(){
			this.$emit('userchange', this.userName);
		}
	}
});
new Vue({
    el: "#app",
    data: {
        name: 'Tom'
    },
	methods:{
		change: function(value){
			this.name = value;
		}
	}
});
</script>
</body>
</html>

В данном случае определяется событие userchange. В реальности в JavaScript не существует подобного события, мы его определяем сами.

В шаблоне компонента элемент ввода связан двусторонней привязкой со значением со свойством userName. Также для этого элемента установлен обработчик события input:

<input type="text" v-model="userName" v-on:input="onUserChange" />

То есть при вводе в это текстовое поле будет вызываться метод onUserChange. В этом методе через вызов this.$emit('userchange', this.userName); генерируем событие userchange и передаем в этом событии измененное значение свойства userName (так как это свойство связано двусторонней привязкой с полем ввода, то при вводе в текстовое поле изменится и свойство user).

onUserChange: function(){
	this.$emit('userchange', this.userName);
}

Чтобы отловить это событие в объекте Vue на дочернем компоненте определен атрибут v-on:userchange:

<useredit :user="name" v-on:userchange="change"></useredit>

То есть поскольку в дочернем компоненте генерируется событие userchange, то соответственно здесь и атрибут имеет определение v-on:userchange. Этому событию сопоставлен метод change:

change: function(value){
	this.name = value;
}

Параметр value представляет то значение, которое передается в дочернем компоненте через вызов this.$emit('userchange', this.userName);, то есть this.userName.

В итоге при вводе данных в дочернем компоненте useredit сработает обработчик события input - метод onUserChange, который сгенерирует событие namechange, которое в свою очередь будет обработано в родительском объекте в методе change.

Communication between child and parent component in Vue.js

Модификатор sync

Начиная с версии 2.3 был добавлен модификатор sync, который позволяет в ряде случаев сократить код использования событий. В частности, перепишем предыдущий пример следующим образом:

<!DOCTYPE html>
<html>
<head>
<title>Компоненты Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
    <h2>Hello, {{name}}</h2>
    <useredit :user.sync="name"></useredit>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script>
Vue.component('useredit', {
    props: ["user"],
	data: function () {
      return { userName: this.user}
    },
    template: '<div><input type="text" v-model="userName" v-on:input="onUserChange" /><p>Name: {{userName}}</p></div>',
    methods: {
        onUserChange: function(){
			this.$emit('update:user', this.userName)
        }
    }
});
new Vue({
    el: "#app",
    data: {
        name: 'Tom'
    }
});
</script>
</body>
</html>

В данном случае строка

<useredit :user.sync="name"></useredit>

будет сокращенем строки:

<useredit :user="name" v-on:update:user="val => name = val"></useredit>

Но в дочернем компоненте также необходимо вызывать данное событие:

onUserChange: function(){
	this.$emit('update:user', this.userName)
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850