Vue.js предоставляет мощный механизм для взаимодействия компонентов
через пользовательские события, что особенно важно при
построении сложной архитектуры с вложенными компонентами. Основной
инструмент для этого — метод $emit.
$emitМетод $emit позволяет дочернему компоненту
отправлять событие родителю. Его синтаксис:
this.$emit('имя-события', payload)
Пример:
// Дочерний компонент
export default {
methods: {
notifyParent() {
this.$emit('update', { message: 'Данные обновлены' });
}
}
}
<!-- Родительский компонент -->
<ChildComponent @update="handleUpdate" />
export default {
methods: {
handleUpdate(payload) {
console.log(payload.message); // 'Данные обновлены'
}
}
}
$emit поддерживает передачу нескольких аргументов:
this.$emit('event-name', arg1, arg2, arg3)
Родитель может получить их через соответствующий обработчик:
<ChildComponent @event-name="handleEvent" />
methods: {
handleEvent(arg1, arg2, arg3) {
console.log(arg1, arg2, arg3);
}
}
Использование нескольких аргументов удобно для передачи структурированных данных без создания отдельных объектов, однако в большинстве случаев предпочтительно использовать один объект, чтобы избежать путаницы.
v-on с
модификаторамиVue позволяет обрабатывать события с помощью модификаторов:
.stop — event.stopPropagation().prevent — event.preventDefault().capture — слушатель с фазой захвата.once — обработка события один раз.passive — слушатель пассивный, оптимизация для
скроллингаПример:
<ChildComponent @update.once.prevent="handleUpdate" />
В этом случае событие обработается один раз, и действие по умолчанию будет предотвращено.
defineEmits (Vue 3, Composition
API)Для компонентов на Composition API Vue 3 введена функция
defineEmits:
<script setup>
const emit = defineEmits(['update', 'delete'])
function notify() {
emit('update', { id: 1 })
}
</script>
const emit = defineEmits({
update: (payload) => typeof payload.id === 'number',
delete: (id) => typeof id === 'number'
})
Попытка вызвать событие с неправильным типом аргумента приведет к предупреждению в консоли.
Для передачи события через несколько уровней компонентов используют:
$emit.Пример ретрансляции:
export default {
emits: ['update'],
methods: {
handleChildUpdate(payload) {
this.$emit('update', payload)
}
}
}
<GrandchildComponent @update="handleChildUpdate" />
Рекомендации по именованию пользовательских событий:
update-item)
вместо camelCase (updateItem) при использовании в
шаблонах.delete-item, toggle-visibility).emits в компонентах
Vue 3 повышает читаемость и безопасность кода.Можно динамически формировать имена событий:
const eventName = `update-${item.id}`
this.$emit(eventName, item)
Родительский компонент может обрабатывать их через v-on с вычисляемыми ключами:
<ChildComponent v-for="item in items" :key="item.id" @update-[item.id]="handleUpdate" />
В Vue 3 поддерживается синтаксис v-on="object" для
передачи множества обработчиков динамически:
const handlers = {
'update-1': () => {},
'update-2': () => {}
}
<ChildComponent v-on="handlers" />
Использование $emit и props обеспечивает
односторонний поток данных, что повышает
предсказуемость приложения и упрощает отладку.
$emit обеспечивает чистую и предсказуемую связь
компонентов.emits в Vue 3 повышает
безопасность и контроль типов.Эти принципы формируют основу архитектуры компонентов Vue.js, где каждая часть приложения остается изолированной, но гибко взаимодействующей с другими.