J'essaie d'utiliser la directive on click dans un composant mais cela ne semble pas fonctionner. Lorsque je clique sur le composant, rien ne se passe lorsque je devrais avoir un «clic sur un test» dans la console. Je ne vois aucune erreur dans la console, donc je ne sais pas ce que je fais de mal.
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 (le composant)
<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
la source
la source
@click.native="testFunction"
Je pense que la
$emit
fonction fonctionne mieux pour ce que je pense que vous demandez. Il garde votre composant séparé de l'instance Vue afin qu'il soit réutilisable dans de nombreux contextes.Utilisez-le en HTML
la source
@click="$emit('click')"
et de cette façon, le composant parent utilise simplement le standard@click
@click="$emit('click')"
.C'est la réponse de @Neps mais avec des détails.
Remarque : la réponse de @ Saurabh est plus adaptée si vous ne souhaitez pas modifier votre composant ou n'y avez pas accès.
Pourquoi @click ne fonctionne-t-il pas?
Les composants sont compliqués. Un composant peut être un petit wrapper de boutons fantaisie, et un autre peut être une table entière avec un tas de logique à l'intérieur. Vue ne sait pas exactement à quoi vous vous attendez lors de la liaison
v-model
ou de l'utilisation,v-on
donc tout cela devrait être traité par le créateur du composant.Comment gérer l'événement de clic
Selon la documentation Vue ,
$emit
transmet les événements au parent. Exemple tiré de la documentation:Dossier principal
Composant
(
@
est lev-on
raccourci )Le composant gère l'
click
événement natif et émet le parent@enlarge-text="..."
enlarge-text
peut être remplacé parclick
pour donner l'impression que nous gérons un événement de clic natif:Mais ce n'est pas tout.
$emit
permet de passer une valeur spécifique avec un événement. Dans le cas de nativeclick
, la valeur est MouseEvent (événement JS qui n'a rien à voir avec Vue).Vue stocke cet événement dans une
$event
variable. Il est donc préférable d'émettre$event
avec un événement pour créer l'impression de l'utilisation de l'événement natif:la source
Un peu verbeux mais voici comment je le fais:
@click="$emit('click', $event)"
la source
$emit
mais rien ne se passe. Dois-je faire quelque chose en plus de$emit
? jsfiddle.net/xwvhy6a3Comme mentionné par Chris Fritz (Vue.js Core Team Emeriti ) dans VueCONF US 2019
Avec Vue 2
En utilisant
$listeners
:Donc, si vous utilisez Vue 2, une meilleure option pour résoudre ce problème serait d'utiliser une logique de wrapper entièrement transparente . Pour cela, Vue fournit une
$listeners
propriété contenant un objet d'écouteurs utilisés sur le composant. Par exemple:et puis nous avons juste besoin d'ajouter
v-on="$listeners"
autest
composant comme:Test.vue (composant enfant)
Maintenant, le
<test>
composant est un wrapper totalement transparent , ce qui signifie qu'il peut être utilisé exactement comme un<div>
élément normal : tous les écouteurs fonctionneront, sans le.native
modificateur.Démo:
En utilisant la
$emit
méthode:Nous pouvons également utiliser la
$emit
méthode à cet effet, qui nous aide à écouter les événements des composants enfants dans le composant parent. Pour cela, nous devons d'abord émettre un événement personnalisé à partir du composant enfant comme:Test.vue (composant enfant)
Important: utilisez toujours kebab-case pour les noms d'événements. Pour plus d'informations et une démonstration de ce point, veuillez consulter cette réponse: VueJS passant la valeur calculée du composant au parent .
Maintenant, nous avons juste besoin d'écouter cet événement personnalisé émis dans le composant parent comme:
App.vue
Donc, fondamentalement, au lieu de
v-on:click
ou de la sténographie,@click
nous utiliserons simplementv-on:my-event
ou simplement@my-event
.Démo:
Avec Vue 3
Utilisation
v-bind="$attrs"
:Vue 3 va nous faciliter la vie à bien des égards. L'un des exemples est qu'il nous aidera à créer un wrapper transparent plus simple avec très moins de configuration en utilisant simplement
v-bind="$attrs"
. En utilisant ceci sur les composants enfants, non seulement notre écouteur fonctionnera directement à partir du parent, mais aussi tout autre attribut fonctionnera également comme s'il était normal<div>
.Donc, en ce qui concerne cette question, nous n'aurons pas besoin de mettre à jour quoi que ce soit dans Vue 3 et votre code fonctionnera toujours correctement, tout comme
<div>
l'élément racine ici et il écoutera automatiquement tous les événements enfants.Démo n ° 1:
Mais pour les composants complexes avec des éléments imbriqués où nous devons appliquer des attributs et des événements à main
<input />
au lieu de l'étiquette parent, nous pouvons simplement utiliserv-bind="$attrs"
Démo n ° 2:
la source
Les événements natifs des composants ne sont pas directement accessibles à partir des éléments parents. Au lieu de cela, vous devriez essayer
v-on:click.native="testFunction"
, ou vous pouvez également émettre un événement à partir duTest
composant. Commev-on:click="$emit('click')"
.la source
De la documentation :
En raison des limitations de JavaScript, Vue ne peut pas détecter les modifications suivantes dans un tableau:
Dans mon cas, je suis tombé sur ce problème lors de la migration d'Angular vers VUE. Le correctif était assez facile, mais vraiment difficile à trouver:
la source