web-dev-qa-db-fra.com

Vue v-on: le clic ne fonctionne pas sur le composant

J'essaie d'utiliser la directive on click à l'intérieur d'un composant, mais cela ne semble pas fonctionner. Lorsque je clique sur le composant, rien ne se passe lorsque je devrais avoir un "test effectué sur" dans la console. Je ne vois aucune erreur dans la console, donc je ne sais pas ce que je fais 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>
117
Javier Cárdenas

Si vous souhaitez écouter un événement natif sur l'élément racine d'un composant, vous devez utiliser le modificateur . Native pour v-on, comme suit:

<template>
  <div id="app">
    <test v-on:click.native="testFunction"></test>
  </div>
</template>

ou en abrégé, comme suggéré dans le commentaire, vous pouvez également:

<template>
  <div id="app">
    <test @click.native="testFunction"></test>
  </div>
</template>
223
Saurabh

Je pense que la fonction $emit fonctionne mieux pour ce que je pense que vous demandez. Il maintient votre composant séparé de l'instance Vue afin qu'il soit réutilisable dans de nombreux contextes.

<template>
  <div id="app">
    <test @click="$emit('test-click')></test>
  </div>
</template>

Utilisez-le en HTML

<test @test-click="testFunction">
16
Jim McNeely

C'est le @ Neps 'answer mais avec des détails.


Note : La réponse de @ Saurabh est plus approprié si vous ne souhaitez pas modifier votre composant ou si vous n'avez pas accès à il.


Pourquoi @click ne fonctionne-t-il pas?

Les composants sont compliqués. Un composant peut être une petite enveloppe de boutons fantaisie, et un autre peut être une table entière avec beaucoup de logique à l'intérieur. Vue ne sait pas exactement ce à quoi vous vous attendez lorsque bind v-model ou n'utilise v-on donc tout cela doit être traité par le créateur du composant.

Comment gérer un événement click

Selon Vue docs , $emit transmet les événements au parent. Exemple de docs:

Fichier principal

<blog-post
  @enlarge-text="onEnlargeText"
/>

Composant

<button @click="$emit('enlarge-text')">
  Enlarge text
</button>

(@ est le v-onabrégé )

Le composant gère l'événement click natif et émet le @enlarge-text="..." du parent

enlarge-text peut être remplacé par click pour donner l'impression que nous gérons un événement de clic natif:

<blog-post
  @click="onEnlargeText"
></blog-post>
<button @click="$emit('click')">
  Enlarge text
</button>

Mais ce n'est pas tout. $emit permet de passer une valeur spécifique avec un événement. Dans le cas de click native, la valeur est MouseEvent (événement JS n'ayant rien à voir avec Vue).

Vue enregistre cet événement dans une variable $event. Il est donc préférable d'émettre $event avec un événement pour créer l'impression d'utilisation d'un événement natif:

<button v-on:click="$emit('click', $event)">
  Enlarge text
</button>
8
OddMorning

Un peu verbeux mais voici comment je le fais:

@click="$emit('click', $event)"

5
Neps

Les événements natifs de composants ne sont pas directement accessibles à partir d'éléments parents. Au lieu de cela, vous devriez essayer v-on:click.native="testFunction", ou vous pouvez également émettre un événement à partir du composant Test. Comme v-on:click="$emit('click')".

5
user4846835