Події компонентів
Ця сторінка передбачає, що ви вже прочитали основи компонентів. Прочитайте це спочатку, якщо ви новачок у компонентах.
Випромінювання та прослуховування подій
Компонент може випромінювати спеціальні події безпосередньо у виразах шаблону (наприклад, в обробнику v-on
), використовуючи вбудований метод $emit
:
template
<!-- MyComponent -->
<button @click="$emit('someEvent')">натиснути</button>
Батьки можуть прослуховувати це за допомогою v-on
:
template
<MyComponent @some-event="callback" />
Модифікатор .once
також підтримується слухачами подій компонентів:
template
<MyComponent @some-event.once="callback" />
Подібно до компонентів і атрибутів, імена подій забезпечують автоматичне перетворення регістру. Зауважте, що ми створили подію camelCase, але можемо прослухати її за допомогою kebab-case слухача у батьківських компонентах. Як і у випадку з регістром імені реквізиту, ми радимо використовувати в шаблонах прослуховувачі подій kebab-case.
TIP
На відміну від нативних подій DOM, події, створені компонентом, не випливають. Ви можете прослуховувати лише події, які випромінює прямий дочірній компонент. Якщо є потреба в спілкуванні між братськими або глибоко вкладеними компонентами, використовуйте зовнішню шину подій або глобальне рішення для керування станом.
Аргументи події
Іноді корисно випромінювати конкретне значення з подією. Наприклад, ми можемо захотіти, щоб компонент <BlogPost>
відповідав за те, на скільки збільшити текст. У таких випадках ми можемо передати додаткові аргументи в $emit
, щоб надати це значення:
template
<button @click="$emit('increaseBy', 1)">
Збільшити на 1
</button>
Тоді, коли ми прослуховуємо подію в батьківському компоненті, ми можемо використовувати вбудовану функцію-стрілку як прослуховувач, що дозволяє отримати доступ до аргументу події:
template
<MyButton @increase-by="(n) => count += n" />
Або, якщо обробником події є метод:
template
<MyButton @increase-by="increaseCount" />
Тоді значення буде передано як перший параметр цього методу:
js
function increaseCount(n) {
count.value += n
}
TIP
Усі додаткові аргументи, передані в $emit()
після назви події будуть перенаправлені слухачу. Наприклад, за допомогою $emit('foo', 1, 2, 3)
функція слухача отримає три аргументи.
Оголошення переданих подій
Компонент може явно оголосити події, які будуть випромінюватись за допомогою макросу defineEmits()
:
vue
<script setup>
defineEmits(['inFocus', 'submit'])
</script>
Метод $emit
, який ми використовували в <template>
, недоступний у розділі <script setup>
компонента, але defineEmits()
повертає еквівалентну функцію, яку ми можемо натомість використати:
vue
<script setup>
const emit = defineEmits(['inFocus', 'submit'])
function buttonClick() {
emit('submit')
}
</script>
Макрос defineEmits()
не можна використовувати всередині функції, його потрібно розмістити безпосередньо в <script setup>
, як у прикладі вище.
Якщо ви використовуєте явну функцію setup
замість <script setup>
, події слід оголошувати за допомогою опції emit
і emit
функція доступна в контексті setup()
:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, ctx) {
ctx.emit('submit')
}
}
Як і інші властивості контексту setup()
, emit
можна безпечно деструктурувати:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, { emit }) {
emit('submit')
}
}
Параметр emits
і макрос defineEmits()
також підтримують синтаксис об’єкта. Якщо ви використовуєте TypeScript, ви можете вводити аргументи, що дозволяє нам виконувати перевірку під час виконання корисного навантаження випущених подій:
vue
<script setup>
const emit = defineEmits({
submit(payload: { email: string, password: string }) {
// повертає `true` або `false`, щоб вказати,
// що перевірка пройшла/не пройшла
}
})
</script>
Якщо ви використовуєте TypeScript з <script setup>
, також можна оголосити події за допомогою суто анотацій:
vue
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
</script>
Детальніше: типізація події компонентів
Незважаючи на те, що це необов’язково, рекомендується визначати всі випромінювані події, щоб краще задокументувати, як має працювати компонент. Це також дозволяє Vue виключати відомих слухачів із прохідних атрибутів, уникаючи крайніх випадків, спричинених подіями DOM, які вручну випромінюються стороннім кодом.
TIP
Якщо власну подію (наприклад, click
) визначено в параметрі emits
, слухач тепер стежитиме лише за подіями click
, що випромінюються компонентом, і більше не відповідатиме на власні події click
.
Перевірка подій
Подібно до перевірки типу реквізитів, подію можна перевірити, якщо її визначено за допомогою синтаксису об’єкта, а не синтаксису масиву.
Щоб додати перевірку, події призначається функція, яка отримує аргументи, передані в emit
викликає і повертає логічне значення, щоб вказати, подія дійсна чи ні.
vue
<script setup>
const emit = defineEmits({
// Без перевірки
click: null,
// Перевірка події надсилання
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Недійсні данні події надсилання!')
return false
}
}
})
function submitForm(email, password) {
emit('submit', { email, password })
}
</script>
Події як реквізити
Ви також можете оголосити та передати events
як props
, додавши on
перед назвою події з великої літери.
Використання props.onEvent
має іншу поведінку, ніж використання emit('event')
, оскільки перше передасть лише обробку прослухувача на основі властивості (@event
або :on-event
).
WARNING
Якщо передано і :onEvent
, і @event
, props.onEvent
може бути масивом функцій
замість функції
, така поведінка не є стабільною та може змінитися в майбутньому.
Через це рекомендується використовувати emit('event')
замість props.onEvent
під час випромінювання подій.