← Назад к вопросам

Как делегируешь событие во Vue?

2.2 Middle🔥 191 комментариев
#Vue.js

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Делегирование событий во 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() помогает найти нужный элемент
  • Делегирование снижает потребление памяти и улучшает производительность
Как делегируешь событие во Vue? | PrepBro