Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Делегирование событий во Vue
Делегирование событий — это техника, при которой один обработчик события устанавливается на родительский элемент и обрабатывает события от всех дочерних элементов. Это снижает количество слушателей и улучшает производительность при большом количестве элементов.
Встроенное делегирование в Vue
В отличие от vanilla JavaScript, где нужно вручную проверять event.target, Vue нативно использует делегирование при привязке событий через @ или v-on.
Основной синтаксис
1. Привязка события через @:
// Шаблон Vue
<div @click="handleClick">
<button>Кнопка 1</button>
<button>Кнопка 2</button>
<button>Кнопка 3</button>
</div>
// Методы
methods: {
handleClick(event) {
console.log('Нажата кнопка:', event.target.textContent);
}
}
В этом примере один обработчик handleClick на <div> обработает клики по всем кнопкам внутри него.
2. Использование v-on:
<ul v-on:click="selectItem">
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
data() {
return {
items: [
{ id: 1, name: 'Элемент 1' },
{ id: 2, name: 'Элемент 2' }
]
};
}
Модификаторы событий
Vue предоставляет удобные модификаторы:
Модификатор .self — обработка только на самом элементе:
<div @click.self="handleClick">
<!-- Клик по div обработается -->
<button>Кнопка</button>
<!-- Клик по кнопке НЕ обработается -->
</div>
Модификатор .stop — остановка всплытия:
<div @click="parentClick">
<button @click.stop="buttonClick">Кнопка</button>
</div>
methods: {
parentClick() {
console.log('Родитель');
},
buttonClick() {
console.log('Кнопка');
// event.stopPropagation() выполнится автоматически
}
}
Модификатор .prevent:
<form @submit.prevent="handleSubmit">
<button type="submit">Отправить</button>
</form>
Делегирование в списках
Неэффективный способ (без делегирования):
<!-- 1000 обработчиков для 1000 элементов -->
<li v-for="item in items" @click="handleClick(item)">
{{ item.name }}
</li>
Оптимальный способ (с делегированием):
<ul @click="handleItemClick" class="item-list">
<li v-for="item in items" :key="item.id" :data-id="item.id">
{{ item.name }}
</li>
</ul>
data() {
return {
items: Array.from({ length: 1000 }, (_, i) => ({
id: i + 1,
name: `Элемент ${i + 1}`
}))
};
}
methods: {
handleItemClick(event) {
const li = event.target.closest('li');
if (li) {
const itemId = li.dataset.id;
console.log('Выбран:', itemId);
this.selectItem(itemId);
}
}
}
Делегирование с .capture
Фаза захвата (capture) и всплытия (bubble):
<div @click.capture="handleCapture">
<button @click="handleBubble">Кнопка</button>
</div>
methods: {
handleCapture(event) {
console.log('Фаза захвата');
},
handleBubble(event) {
console.log('Фаза всплытия');
}
}
Сравнение: Vue vs Vanilla JavaScript
Vanilla JS:
document.getElementById('list').addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
console.log('Выбран:', event.target.textContent);
}
});
Vue:
<ul @click="selectItem">
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
Выводы
- Vue автоматически использует делегирование при привязке событий
- Используй @click на контейнере для больших списков
- Модификаторы .self, .stop, .prevent упрощают работу
- Метод closest() помогает найти нужный элемент
- Делегирование снижает потребление памяти и улучшает производительность