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
$emit
funció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-model
o usasv-on
por lo que todo eso debe ser procesado por el creador del componente.Cómo manejar el evento click
Según los documentos de Vue ,
$emit
pasa los eventos a los padres. Ejemplo de documentos:Archivo principal
Componente
(
@
es lav-on
taquigrafía )El componente maneja
click
eventos nativos y emite los padres@enlarge-text="..."
enlarge-text
puede reemplazarseclick
para que parezca que estamos manejando un evento de clic nativo:Pero eso no es todo.
$emit
permite 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
$event
variable. Por lo tanto, sería mejor emitir$event
un 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
$emit
pero 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
$listeners
propiedad que contiene un objeto de oyentes que se utilizan en el componente. Por ejemplo:y luego solo necesitamos agregar
v-on="$listeners"
altest
componente 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.native
modificador.Manifestación:
Utilizando el
$emit
método:También podemos usar el
$emit
mé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:click
o la taquigrafía@click
simplemente usaremosv-on:my-event
o 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 elTest
componente. 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