vue-05(自定义事件)

自定义事件:在父组件中发出和处理事件

自定义事件是 Vue.js 中组件通信的基石,它允许子组件向其父组件发出事件信号。此机制使您能够通过解耦组件逻辑和提高可重用性来构建更具交互性和动态性的用户界面。了解如何正确发出和处理自定义事件对于创建复杂的 Vue.js 应用程序至关重要。

发出自定义事件

$emit 方法是组件触发自定义事件的主要方式。这个方法在每个 Vue 组件实例上都可用,并接受两个参数:事件名称(字符串)和可选的有效负载(你想传递给父组件的任何数据)。

基本事件

事件发出的最简单形式涉及使用事件名称调用 $emit

html 复制代码
<template>
  <button @click="handleClick">Click me</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      this.$emit('my-custom-event');
    }
  }
};
</script>

在此示例中,单击按钮时,将执行 handleClick 方法,该方法将发出 my-custom-event 事件。然后,父组件可以侦听此事件。

使用 Payload 发出事件

通常,您需要将数据与事件一起发送。这就是可选的 payload 参数的用武之地。

html 复制代码
<template>
  <button @click="handleClick">Add Item</button>
</template>

<script>
export default {
  data() {
    return {
      newItem: 'Example Item'
    };
  },
  methods: {
    handleClick() {
      this.$emit('add-item', this.newItem);
    }
  }
};
</script>

在这里,当单击按钮时,将发出 add-item 事件,并将 this.newItem 的值作为有效负载传递。父组件可以在其事件处理程序中访问此有效负载。

事件命名约定

虽然从技术上讲,你可以使用任何字符串作为事件名称,但最好使用 kebab-case(例如,my-custom-eventadd-item)。此约定与 HTML 属性命名一致,并提高了可读性。

本机事件与自定义事件

区分本机 DOM 事件(如 clickmouseoversubmit)和自定义事件非常重要。原生事件由浏览器触发,而自定义事件由 Vue 组件使用 $emit 触发。虽然您可以侦听组件上的本机事件,但自定义事件为组件提供了一种更加结构化和可控的通信方式。

处理父组件中的自定义事件

父组件可以使用 v-on 指令(或其简写 @)监听其子组件发出的自定义事件。

侦听事件

要监听事件,你可以在父组件模板中的子组件标签上使用 v-on(或 @)。

html 复制代码
<template>
  <div>
    <child-component @my-custom-event="handleCustomEvent"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleCustomEvent() {
      console.log('Custom event received!');
    }
  }
};
</script>

在此示例中,父组件正在侦听 ChildComponent 发出的 my-custom-event 事件。当事件被触发时,将执行父组件中的 handleCustomEvent 方法。

访问 Payload

如果子组件发出带有有效负载的事件,则父组件可以将有效负载作为事件处理程序的参数进行访问。

html 复制代码
<template>
  <div>
    <child-component @add-item="addItem"></child-component>
    <ul>
      <li v-for="item in items" :key="item">{{ item }}</li>
    </ul>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      items: []
    };
  },
  methods: {
    addItem(newItem) {
      this.items.push(newItem);
    }
  }
};
</script>

在这种情况下,addItem 方法接收 ChildComponent 发出的 newItem 值,并将其添加到 items 数组中。

内联事件处理程序

您还可以直接在模板中使用内联事件处理程序。

html 复制代码
<template>
  <div>
    <child-component @my-custom-event="message = 'Event received!'"></child-component>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      message: ''
    };
  }
};
</script>

这对于简单的事件处理逻辑很有用,但对于更复杂的逻辑,通常最好使用专用方法。

事件修饰符

Vue 提供了事件修饰符,可以与 v-on 一起使用来修改事件的处理方式。虽然某些修饰符特定于本机 DOM 事件(例如,.prevent.stop),但其他修饰符也可用于自定义事件。我们将在下一课中更详细地探讨事件修饰符。

实际示例和演示

让我们考虑这样一个场景:您有一个 ProductCard 组件,该组件显示产品信息并允许用户将产品添加到他们的购物车。

ProductCard.vue (子组件):

html 复制代码
<template>
  <div class="product-card">
    <h3>{{ product.name }}</h3>
    <p>{{ product.description }}</p>
    <button @click="addToCart">Add to Cart</button>
  </div>
</template>

<script>
export default {
  props: {
    product: {
      type: Object,
      required: true
    }
  },
  methods: {
    addToCart() {
      this.$emit('add-to-cart', this.product);
    }
  }
};
</script>

<style scoped>
.product-card {
  border: 1px solid #ccc;
  padding: 10px;
  margin-bottom: 10px;
}
</style>

ProductList.vue (父组件):

html 复制代码
<template>
  <div>
    <h2>Product List</h2>
    <product-card
      v-for="product in products"
      :key="product.id"
      :product="product"
      @add-to-cart="handleAddToCart"
    ></product-card>
    <h3>Cart</h3>
    <ul>
      <li v-for="item in cart" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import ProductCard from './ProductCard.vue';

export default {
  components: {
    ProductCard
  },
  data() {
    return {
      products: [
        { id: 1, name: 'Product A', description: 'Description of Product A' },
        { id: 2, name: 'Product B', description: 'Description of Product B' }
      ],
      cart: []
    };
  },
  methods: {
    handleAddToCart(product) {
      this.cart.push(product);
    }
  }
};
</script>

在此示例中,ProductCard 组件在单击"Add to Cart"按钮时发出 add-to-cart 事件,并将 product 对象作为有效负载传递。ProductList 组件侦听此事件并将产品添加到 cart 数组中。

相关推荐
leoZ2316 小时前
Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践
vue.js·spring boot·架构
荒诞英雄10 小时前
从 17MB Vendor 大包到按需加载:Vite 多入口 Vue 组件库首屏优化实践
vue.js·vite
jsonbro10 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式
Cobyte12 小时前
23.Vue Vapor 组件 attrs 的实现
前端·javascript·vue.js
斯特凡今天也很帅13 小时前
xml页面可以打开,不报错,但是显示数据的地方也不显示,我是怎么解决的
xml·vue.js
柯克七七14 小时前
给老项目加了 TypeScript,本来只想自己爽,结果全公司代码审查标准被我抬高了
前端·vue.js·typescript
自然 醒16 小时前
前端如何实现在线预览office常见文件功能?
前端·vue.js
肉肉不吃 肉17 小时前
前端调试跨域如何解决
前端·vue.js
卓怡学长17 小时前
w268基于springboot + vue 物流系统
java·数据库·vue.js·spring boot·spring·intellij-idea
2601_9628517417 小时前
计算机毕业设计之基于SSM的网络安全课程资源分享平台
vue.js·算法·安全·web安全·yolo·目标检测·课程设计