Estoy tratando de usar la directiva de clic dentro de un componente, pero no parece funcionar. Cuando hago clic en el componente, no ocurre nada cuando debo hacer un 'clic de prueba' en la consola. No veo ningún error en la consola, así que no sé qué estoy haciendo 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 (el componente)
<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
fuente
fuente

@click.native="testFunction"Creo que la
$emitfunción funciona mejor para lo que creo que estás pidiendo. Mantiene su componente separado de la instancia de Vue para que sea reutilizable en muchos contextos.Úselo en HTML
fuente
@click="$emit('click')"y de esa manera el componente principal solo usa el normal@click@click="$emit('click')".Es la respuesta de @Neps pero con detalles.
Nota : la respuesta de @ Saurabh es más adecuada si no desea modificar su componente o no tiene acceso a él.
¿Por qué no puede @click simplemente trabajar?
Los componentes son complicados. Un componente puede ser un pequeño envoltorio de botones elegante, y otro puede ser una tabla completa con un montón de lógica dentro. Vue no sabe qué esperas exactamente cuando unes
v-modelo usasv-onpor lo que todo eso debe ser procesado por el creador del componente.Cómo manejar el evento click
Según los documentos de Vue ,
$emitpasa los eventos a los padres. Ejemplo de documentos:Archivo principal
Componente
(
@es lav-ontaquigrafía )El componente maneja
clickeventos nativos y emite los padres@enlarge-text="..."enlarge-textpuede reemplazarseclickpara que parezca que estamos manejando un evento de clic nativo:Pero eso no es todo.
$emitpermite pasar un valor específico con un evento. En el caso de nativeclick, el valor es MouseEvent (evento JS que no tiene nada que ver con Vue).Vue almacena ese evento en una
$eventvariable. Por lo tanto, sería mejor emitir$eventun evento para crear la impresión del uso de eventos nativos:fuente
Un poco detallado pero así es como lo hago:
@click="$emit('click', $event)"fuente
$emitpero no pasa nada. ¿Necesito hacer algo además de$emit? jsfiddle.net/xwvhy6a3Como mencionó Chris Fritz (Vue.js Core Team Emeriti ) en VueCONF US 2019
Con Vue 2
Utilizando
$listeners:Entonces, si está utilizando Vue 2, una mejor opción para resolver este problema sería usar una lógica de envoltura totalmente transparente . Para esto, Vue proporciona una
$listenerspropiedad que contiene un objeto de oyentes que se utilizan en el componente. Por ejemplo:y luego solo necesitamos agregar
v-on="$listeners"altestcomponente como:Test.vue (componente hijo)
Ahora el
<test>componente es un contenedor totalmente transparente , lo que significa que se puede usar exactamente como un<div>elemento normal : todos los oyentes funcionarán, sin el.nativemodificador.Manifestación:
Utilizando el
$emitmétodo:También podemos usar el
$emitmétodo para este propósito, que nos ayuda a escuchar eventos de componentes secundarios en el componente principal. Para esto, primero debemos emitir un evento personalizado desde un componente secundario como:Test.vue (componente hijo)
Importante: siempre use kebab-case para los nombres de los eventos. Para obtener más información y una demostración de este punto, consulte esta respuesta: VueJS pasa el valor calculado del componente al padre .
Ahora, solo necesitamos escuchar este evento personalizado emitido en el componente principal como:
App.vue
Entonces, básicamente en lugar de
v-on:clicko la taquigrafía@clicksimplemente usaremosv-on:my-evento simplemente@my-event.Manifestación:
Con Vue 3
Utilizando
v-bind="$attrs":Vue 3 nos hará la vida mucho más fácil de muchas maneras. Uno de los ejemplos es que nos ayudará a crear un contenedor transparente más simple con muy poca configuración simplemente usando
v-bind="$attrs". Al usar esto en componentes secundarios, no solo nuestro oyente trabajará directamente desde el padre, sino que también cualquier otro atributo también funcionará de manera normal<div>.Entonces, con respecto a esta pregunta, no necesitaremos actualizar nada en Vue 3 y su código seguirá funcionando bien, ya que
<div>es el elemento raíz aquí y escuchará automáticamente todos los eventos secundarios.Demo # 1:
Pero para componentes complejos con elementos anidados donde necesitamos aplicar atributos y eventos a main en
<input />lugar de a la etiqueta principal, simplemente podemos usarv-bind="$attrs"Demo # 2:
fuente
No se puede acceder directamente a los eventos nativos de los componentes desde los elementos principales. En su lugar, debería intentarlo
v-on:click.native="testFunction", o también puede emitir un evento desde elTestcomponente. Al igualv-on:click="$emit('click')".fuente
De la documentación :
Debido a limitaciones en JavaScript, Vue no puede detectar los siguientes cambios en una matriz:
En mi caso, me topé con este problema al migrar de Angular a VUE. La solución fue bastante fácil, pero realmente difícil de encontrar:
fuente