Próbuję użyć dyrektywy on click wewnątrz komponentu, ale wydaje się, że nie działa. Kiedy klikam komponent, nic się nie dzieje, kiedy powinienem otrzymać „kliknięcie testu” w konsoli. Nie widzę żadnych błędów w konsoli, więc nie wiem, co robię źle.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vuetest</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
App.vue
<template>
<div id="app">
<test v-on:click="testFunction"></test>
</div>
</template>
<script>
import Test from './components/Test'
export default {
name: 'app',
methods: {
testFunction: function (event) {
console.log('test clicked')
}
},
components: {
Test
}
}
</script>
Test.vue (składnik)
<template>
<div>
click here
</div>
</template>
<script>
export default {
name: 'test',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
javascript
vue-component
vuejs2
vue.js
Javier Cárdenas
źródło
źródło
@click.native="testFunction"
Myślę, że ta
$emit
funkcja działa lepiej dla tego, o co myślę, że prosisz. Dzięki temu komponent jest oddzielony od instancji Vue, dzięki czemu można go ponownie wykorzystać w wielu kontekstach.Użyj go w HTML
źródło
@click="$emit('click')"
i w ten sposób komponent nadrzędny po prostu używa zwykłego@click
@click="$emit('click')"
.To odpowiedź @Neps, ale ze szczegółami.
Uwaga : odpowiedź @ Saurabh jest bardziej odpowiednia, jeśli nie chcesz modyfikować swojego komponentu lub nie masz do niego dostępu.
Dlaczego @click nie może po prostu działać?
Komponenty są skomplikowane. Jednym komponentem może być mała, fantazyjna obwoluta przycisku, a innym może być cały stół z mnóstwem logiki w środku. Vue nie wie, czego dokładnie oczekujesz po bindowaniu
v-model
lub używaniu,v-on
więc wszystko to powinno zostać przetworzone przez twórcę komponentu.Jak obsługiwać zdarzenie kliknięcia
Zgodnie z docs Vue ,
$emit
przechodzi zdarzenia do rodzica. Przykład z dokumentów:Plik główny
Składnik
(
@
jestv-on
skrótem )Komponent obsługuje natywne
click
zdarzenia i emituje rodzica@enlarge-text="..."
enlarge-text
można zastąpić,click
aby wyglądało na to, że obsługujemy zdarzenie kliknięcia natywnego:Ale to nie wszystko.
$emit
umożliwia przekazanie określonej wartości ze zdarzeniem. W przypadku natywnejclick
wartością jest MouseEvent (zdarzenie JS, które nie ma nic wspólnego z Vue).Vue przechowuje to wydarzenie w
$event
zmiennej. Najlepiej byłoby więc emitować$event
ze zdarzeniem, aby stworzyć wrażenie użycia zdarzenia natywnego:źródło
Trochę rozwlekłe, ale tak to robię:
@click="$emit('click', $event)"
źródło
$emit
ale nic się nie dzieje. Czy muszę coś dodatkowo zrobić$emit
? jsfiddle.net/xwvhy6a3Natywne zdarzenia komponentów nie są bezpośrednio dostępne z elementów nadrzędnych. Zamiast tego powinieneś spróbować
v-on:click.native="testFunction"
, lub możesz również wyemitować zdarzenie zTest
komponentu. Lubięv-on:click="$emit('click')"
.źródło
Jak wspomniał Chris Fritz (Vue.js Core Team Emeriti ) w VueCONF US 2019
Dzięki Vue 2
Za pomocą
$listeners
:Tak więc, jeśli używasz Vue 2, lepszym rozwiązaniem tego problemu byłoby użycie w pełni przezroczystej logiki opakowującej . W tym przypadku Vue udostępnia
$listeners
właściwość zawierającą obiekt detektorów używanych w komponencie. Na przykład:a następnie wystarczy dodać
v-on="$listeners"
dotest
komponentu:Test.vue (składnik potomny)
Teraz
<test>
komponent jest w pełni przezroczystym opakowaniem , co oznacza, że można go używać dokładnie tak, jak zwykłego<div>
elementu: wszyscy słuchacze będą działać bez.native
modyfikatora.Próbny:
Za pomocą
$emit
metody:W
$emit
tym celu możemy również użyć metody, która pomaga nam słuchać zdarzeń komponentów potomnych w komponencie nadrzędnym. W tym celu musimy najpierw wyemitować zdarzenie niestandardowe z komponentu podrzędnego, takie jak:Test.vue (składnik potomny)
Ważne: zawsze używaj kebabów w nazwach wydarzeń. Aby uzyskać więcej informacji i demonstrację dotyczącą tego punktu, sprawdź tę odpowiedź: VueJS przekazuje obliczoną wartość z komponentu do rodzica .
Teraz wystarczy odsłuchać emitowane zdarzenie niestandardowe w komponencie nadrzędnym, takie jak:
App.vue
Tak więc, w zasadzie zamiast
v-on:click
skrótu lub po@click
prostu użyjemyv-on:my-event
lub po prostu@my-event
.Próbny:
Dzięki Vue 3
Używając
v-bind="$attrs"
:Vue 3 znacznie ułatwi nam życie na wiele sposobów. Jednym z przykładów jest to, że pomoże nam to stworzyć prostszą przezroczystą otokę z bardzo mniejszą konfiguracją, po prostu używając
v-bind="$attrs"
. Używając tego na komponentach potomnych, nie tylko nasz odbiornik będzie działał bezpośrednio z rodzica, ale także każdy inny atrybut również będzie działał tak jak normalny<div>
.Tak więc, w odniesieniu do tego pytania, nie będziemy musieli niczego aktualizować w Vue 3, a Twój kod będzie nadal działał dobrze, podobnie jak
<div>
tutaj element główny i automatycznie nasłuchuje wszystkich zdarzeń podrzędnych.Demo nr 1:
Ale w przypadku złożonych komponentów z zagnieżdżonymi elementami, w których musimy zastosować atrybuty i zdarzenia do main
<input />
zamiast do etykiety nadrzędnej, możemy po prostu użyćv-bind="$attrs"
Demo nr 2:
źródło
Z dokumentacji :
Ze względu na ograniczenia JavaScript Vue nie może wykryć następujących zmian w tablicy:
W moim przypadku natknąłem się na ten problem podczas migracji z Angular do VUE. Poprawka była dość łatwa, ale naprawdę trudna do znalezienia:
źródło