Add Event Listeners Dynamically on Children

To add an event listener dynamically to a child component, use the lwc:on directive.

Let’s say you have a component spreadOnEvent with a child component spreadOnEventChild. You want to pass properties to the child component with an event handler.

1<!-- spreadOnEvent.html -->
2<template>
3  <c-spread-on-event-child
4    lwc:spread={childProps}
5    lwc:on={eventHandlers}
6  ></c-spread-on-event-child>
7  <p>Custom event received: {customEventDetail}</p>
8</template>

The spreadOnEvent component uses lwc:on to attach a handler for a custom event on the child. The child component dispatches events both when it’s inserted into the DOM and when a button is clicked, sending messages and updated properties back to the parent. The parent component updates its display based on the detail property that’s received from the child component’s events.

1// spreadOnEvent.js
2import { LightningElement } from "lwc";
3
4export default class SpreadOnEvent extends LightningElement {
5  childProps = { name: "James Smith", age: "40" };
6  customEventDetail = "";
7  eventHandlers = {
8    customEvent: this.handleCustomEvent,
9  };
10
11  handleCustomEvent(event) {
12    this.customEventDetail = event.detail.message;
13    this.childProps.name = event.detail.name;
14    this.childProps.age = event.detail.age;
15  }
16}

The child component spreadOnEventChild displays the name and age property values, and a button to dispatch the custom event.

1<!-- spreadOnEventChild -->
2<template>
3  <div>Child Component</div>
4  <p>Name: {name}</p>
5  <p>Age: {age}</p>
6  <lightning-button onclick={handleButtonClick} label="Get custom event"> </lightning-button>
7</template>

On initial load, the name and age properties display “James Smith” and “40”, which are values that are passed down from the parent component. When the button is clicked, the custom event dispatches and sets the values “LWC” and “8” on the child component.

1// spreadOnEventChild.js
2import { LightningElement, api } from "lwc";
3
4export default class SpreadOnEventChild extends LightningElement {
5  @api name;
6  @api age;
7
8  connectedCallback() {
9    // Dispatch a custom event when this component is connected
10    this.dispatchEvent(
11      new CustomEvent("customEvent", {
12        detail: {
13          message: "Hello from child component",
14          name: this.name,
15          age: this.age,
16        },
17      }),
18    );
19  }
20
21  handleButtonClick() {
22    this.dispatchEvent(
23      new CustomEvent("customEvent", {
24        detail: {
25          message: "Button clicked in child component",
26          name: "LWC",
27          age: "8",
28        },
29      }),
30    );
31  }
32}