Tengo una situación como esta: en un componente llamado "ProductForm" tengo un método "addToCart", que agregará algún producto a un carrito en una tienda en línea. Esto se llama mediante un evento de clic de botón.
Ahora agregué un nuevo componente secundario "GiftUpsell", que es esencialmente solo un botón adicional "Agregar al carrito". Pero además debería agregar otro producto, pasado como parámetro a handleAddToCart.
Así que modifiqué el método handleAddToCart en ProductForm para aceptar un parámetro opcional, como se muestra a continuación, y paso este parámetro a través de un evento del componente secundario "GiftUpsell":
ProductForm.vue
<template> <btn @click.native="handleAddToCart">Add to Cart</btn> <gift-upsell @upsellAddToCart="handleAddToCart" /> </template> <script> import GiftUpsell from '~/components/GiftUpsell' export default { components: { GiftUpsell }, methods: { handleAddToCart(upsellLineItem = null) { // ... } } }GiftUpsell.vue
<template> <btn @click.native="upsellAddToCart">Add to cart with upsell</btn> </template> <script> export default { methods: { createUpsellLineItem() { // whatever return some object; }, upsellAddToCart() { const lineItem = createUpsellLineItem(); this.$emit('upsell-add-to-cart', lineItem); } } } El problema ahora es: cuando uso el nuevo botón de agregar al carrito de ventas adicionales, funciona bien. El parámetro lineItem se pasa como el único parámetro para handleAddToCart y la lógica funciona.
Sin embargo, cuando hago clic en el antiguo botón "normal" de agregar al carrito, el método handleAddToCart obtiene el $event como primer parámetro, que no está presente cuando se llama a handleAddToCart a través del evento upsell upsell-add-to-cart .
Esto es confuso. ¿Por qué está presente el parámetro $event cuando no lo necesito, y solo están presentes los parámetros de evento (pero no el objeto de evento) cuando necesito los parámetros? ¿Hay alguna manera de deshacerse de esta inconsistencia?
La directiva v-on pasa automáticamente los datos del evento al método especificado cuando solo se proporciona un nombre de método. Eso es lo que ocurre para ambos enlaces @click en su plantilla, y eso es también lo que permite que los datos emitidos ( lineItem ) lleguen a handleAddToCart .
Estas dos plantillas son equivalentes:
<btn @click.native="handleAddToCart">Add to Cart</btn> <gift-upsell @upsellAddToCart="handleAddToCart" /> <btn @click.native="handleAddToCart($event)">Add to Cart</btn> <gift-upsell @upsellAddToCart="handleAddToCart($event)" /> En el primer enlace <btn @click> , los datos del evento de click del botón ( MouseEvent ) se pasan como argumento a handleAddToCart . Para hacer que el clic de <btn> no pase nada, puede actualizar el enlace para llamar a handleAddToCart sin argumentos:
<btn @click.native="handleAddToCart()">Add to Cart</btn> <gift-upsell @upsellAddToCart="handleAddToCart" /> O sea explícito para ambos enlaces v-on :
<btn @click.native="handleAddToCart()">Add to Cart</btn> <gift-upsell @upsellAddToCart="handleAddToCart($event)" />