Události komponent (Events)
Tato stránka předpokládá, že už jste četli Základy komponent. Pokud jsou pro vás komponenty nové, přečtěte si je jako první.
Vyvolání událostí a naslouchání jim
Komponenta může vysílat (emit) vlastní události přímo ve výrazech šablony (např. ve v-on
handleru) pomocí vestavěné metody $emit
:
template
<!-- MyComponent -->
<button @click="$emit('someEvent')">Klikni na mě</button>
Komponenta rodiče může událostem naslouchat s využitím v-on
:
template
<MyComponent @some-event="callback" />
Event listenery komponenty podporují i modifikátor .once
:
template
<MyComponent @some-event.once="callback" />
Stejně jako komponenty a vlastnosti poskytují názvy událostí automatickou transformaci názvů. Všimněte si, že jsme emitovali událost jako camelCase, ale můžeme jí v komponentě rodiče naslouchat pomocí listeneru s kebab-cased zápisem. Stejně jako v případě velkých a malých písmen v názvech vlastností doporučujeme v šablonách používat kebab-cased event listenery.
TIP
Na rozdíl od nativních DOM událostí, události vysílané komponentou neprobublávají. Můžete naslouchat pouze událostem vysílaným přímo komponentou potomka. Pokud je potřeba komunikovat mezi sourozeneckými nebo hluboce vnořenými komponentami, použijte externí sběrnici událostí (event bus) nebo globální správu stavu.
Parametry událostí
Někdy je užitečné vysílat spolu s událostí určitou hodnotu. Například můžeme chtít, aby komponenta <BlogPost>
určovala, o kolik se má zvětšit text. V takových případech můžeme události $emit
předat další parametry, které tuto hodnotu poskytnou:
template
<button @click="$emit('increaseBy', 1)">
Zvýšit o 1
</button>
Když pak nasloucháme události v komponentě rodiče, můžeme jako listener použít inline arrow funkci, která nám umožní přistupovat k parametrům události:
template
<MyButton @increase-by="(n) => count += n" />
Nebo pokud je event handler funkce:
template
<MyButton @increase-by="increaseCount" />
Pak bude hodnota předána do této funkce jako první parametr:
js
function increaseCount(n) {
count.value += n
}
TIP
Všechny další parametry předané do $emit()
za názvem události budou předány do listeneru. Například při $emit('foo', 1, 2, 3)
obdrží funkce listeneru tři parametry.
Deklarování vysílaných událostí
Komponenta může explicitně deklarovat události, které bude vysílat, pomocí makra defineEmits()
:
vue
<script setup>
defineEmits(['inFocus', 'submit'])
</script>
Metoda $emit
, kterou jsme použili v <template>
, není v sekci <script setup>
komponenty přístupná, ale defineEmits()
vrací ekvivalentní funkci, kterou můžeme použít místo ní:
vue
<script setup>
const emit = defineEmits(['inFocus', 'submit'])
function buttonClick() {
emit('submit')
}
</script>
Makro defineEmits()
nemůže být použito uvnitř funkce, musí být umístěno přímo do <script setup>
jako ve výše uvedeném případě.
Pokud používáte explicitní funkci setup
místo <script setup>
, měly by být události deklarovány pomocí možnosti emits
a funkce emit
je vystavena v kontextu setup()
:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, ctx) {
ctx.emit('submit')
}
}
Stejně jako ostatní vlastnosti kontextu setup()
, emit
může být bezpečně destrukturována:
js
export default {
emits: ['inFocus', 'submit'],
setup(props, { emit }) {
emit('submit')
}
}
Možnost emits
a defineEmits()
makro také podporují objektovou syntaxi. Při použití TypeScriptu je možné typovat parametry, což nám umožňuje provádět runtime validaci obsahu (payload) emitovaných událostí:
vue
<script setup lang="ts">
const emit = defineEmits({
submit(payload: { email: string, password: string }) {
// vrací `true` nebo `false` pro určení,
// zda validace prošla / selhala
}
})
</script>
Pokud používáte TypeScript dohromady se <script setup>
, je také možné deklarovat vysílané události pomocí „pure“ typových anotací:
vue
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
</script>
Více detailů: Typování emitovaných událostí komponenty
Ačkoli to není povinné, doporučuje se definovat všechny vysílané události, aby bylo možné lépe zdokumentovat, jak má komponenta fungovat. Umožňuje to také Vue vyloučit známé listenery z fallthrough atributů, čímž se vyhnete okrajovým případům způsobeným DOM událostmi odesílanými ručně kódem třetí strany.
TIP
Pokud je v možnosti emits
definována nativní událost (např. click
), bude nyní listener naslouchat pouze událostem click
vysílaným komponentou a nebude již reagovat na nativní události click
.
Validace událostí
Podobně jako u validace typů u vlastností lze validovat emitovanou událost, pokud je definována pomocí syntaxe objektu namísto syntaxe pole.
Pro přidání validace je události přiřazena funkce, která obdrží parametry předané do volání emit
a vrátí boolean hodnotu označující, zda je událost platná, nebo ne.
vue
<script setup>
const emit = defineEmits({
// bez validace
click: null,
// validace události `submit`
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Neplatná data události!')
return false
}
}
})
function submitForm(email, password) {
emit('submit', { email, password })
}
</script>