I am trying to understand the difference in child to parent communication when doing with custom event via
this.addEventListener
- by defining method name in child component definition in parent component (
<c-child-component-for-event-prop *onpass**={**fetchValue** }> </c-child-component-for-event-prop>
)
When I do via this.addEventListener
process, I need to mark properties of bubbles and composed both true so parent can listen the communication sent by child. Although the documentation says only bubbles = true should work . Why is that so?
When I do it by defining the custom event name in child component definition name in parent component as described above, even if I mark bubbles and composed as false, still communication goes through and parent component is able to listen. Why?
Posting the code here - child component HTML:
<template>
<p>This is child P tag Made on 10/03/2025</p>
<lightning-card>
<lightning-button label="Child Component" onclick={handleClick}></lightning-button>
<p>{messageFromChild}</p>
</lightning-card>
</template>
Child component Javascript:
import { LightningElement } from 'lwc';
export default class ChildComponentForEventProp extends LightningElement {
message = 'This is from Child';
handleClick() {
const selectEvent = new CustomEvent("buttonclick",
{
bubbles : true,
composed : true,
detail : this.message,
});
this.dispatchEvent(selectEvent);
const selectEventSec = new CustomEvent("pass",
{
bubbles : false,
composed : false,
detail : this.message,
});
this.dispatchEvent(selectEventSec);
}
}
Parent Component HTML:
<template>
<lightning-card>
<h1>Parent Component - {messageFromChild}</h1>
<p>This is Parent P tag</p>
<c-child-component-for-event-prop onpass={fetchValue}> </c-child-component-for-event-prop>
</lightning-card>
</template>
Parent component Javascript:
import { LightningElement } from 'lwc';
export default class ParentComponentForEventProp extends LightningElement {
messageFromChild;
constructor() {
super();
}
renderedCallback() {
// code
this.addEventListener('buttonclick', this.handleButtonClickNewN.bind(this), true);
}
handleButtonClickNewN(event) {
console.log('Came TO PARENT');
this.messageFromChild = event.detail + ' New One';
//event.stopPropagation();
}
fetchValue(event) {
console.log( 'Value from Child LWC is ' + event.detail );
this.messageFromChild = event.detail + 'VIA component definition method';
}
}
I am trying to understand the difference in child to parent communication when doing with custom event via
this.addEventListener
- by defining method name in child component definition in parent component (
<c-child-component-for-event-prop *onpass**={**fetchValue** }> </c-child-component-for-event-prop>
)
When I do via this.addEventListener
process, I need to mark properties of bubbles and composed both true so parent can listen the communication sent by child. Although the documentation says only bubbles = true should work . Why is that so?
When I do it by defining the custom event name in child component definition name in parent component as described above, even if I mark bubbles and composed as false, still communication goes through and parent component is able to listen. Why?
Posting the code here - child component HTML:
<template>
<p>This is child P tag Made on 10/03/2025</p>
<lightning-card>
<lightning-button label="Child Component" onclick={handleClick}></lightning-button>
<p>{messageFromChild}</p>
</lightning-card>
</template>
Child component Javascript:
import { LightningElement } from 'lwc';
export default class ChildComponentForEventProp extends LightningElement {
message = 'This is from Child';
handleClick() {
const selectEvent = new CustomEvent("buttonclick",
{
bubbles : true,
composed : true,
detail : this.message,
});
this.dispatchEvent(selectEvent);
const selectEventSec = new CustomEvent("pass",
{
bubbles : false,
composed : false,
detail : this.message,
});
this.dispatchEvent(selectEventSec);
}
}
Parent Component HTML:
<template>
<lightning-card>
<h1>Parent Component - {messageFromChild}</h1>
<p>This is Parent P tag</p>
<c-child-component-for-event-prop onpass={fetchValue}> </c-child-component-for-event-prop>
</lightning-card>
</template>
Parent component Javascript:
import { LightningElement } from 'lwc';
export default class ParentComponentForEventProp extends LightningElement {
messageFromChild;
constructor() {
super();
}
renderedCallback() {
// code
this.addEventListener('buttonclick', this.handleButtonClickNewN.bind(this), true);
}
handleButtonClickNewN(event) {
console.log('Came TO PARENT');
this.messageFromChild = event.detail + ' New One';
//event.stopPropagation();
}
fetchValue(event) {
console.log( 'Value from Child LWC is ' + event.detail );
this.messageFromChild = event.detail + 'VIA component definition method';
}
}
Share
Improve this question
edited Mar 10 at 18:00
marc_s
756k184 gold badges1.4k silver badges1.5k bronze badges
asked Mar 10 at 17:37
user2456012user2456012
1
1 Answer
Reset to default 0You're observing two different behaviors because of how event propagation works in LWC.
Case 1: Using this.addEventListener
in renderedCallback
Here, you are dynamically adding an event listener to the parent component using this.addEventListener('buttonclick', ...)
.
Why do you need bubbles: true, composed: true
?
Bubbles (
bubbles: true
): Ensures the event travels up from the child component to the parent component in the DOM.Composed (
composed: true
): Allows the event to cross the Shadow DOM boundary, meaning it can escape from the child LWC and be caught by an ancestor (like the parent LWC).
Without composed: true
, the event will not escape the Shadow DOM of the child component, and the parent will not be able to listen to it, even if bubbles
is true.
That's why when you dispatch:
const selectEvent = new CustomEvent("buttonclick", {
bubbles: true,
composed: true,
detail: this.message,
});
this.dispatchEvent(selectEvent);
it works only when both bubbles
and composed
are true
.
Case 2: Using onpass={fetchValue}
in the Parent Component Definition
Here, you're handling the event in the template (onpass={fetchValue}
).
Why does it work even when bubbles
and composed
are false
?
In LWC, event handlers defined in the template (
onpass={fetchValue}
) automatically listen for events coming from the child component, even if they do not bubble.Since the event is fired directly from the child and the parent has explicitly declared
onpass={fetchValue}
, LWC automatically connects the child’s event to the parent’s handler.The event doesn't need to travel via bubbling because LWC’s event binding mechanism directly associates the child’s event with the handler in the parent.
That's why this event:
const selectEventSec = new CustomEvent("pass", {
bubbles: false,
composed: false,
detail: this.message,
});
this.dispatchEvent(selectEventSec);
is still received by the parent’s fetchValue
method, even though the event does not bubble or escape the Shadow DOM.
Best Practices
If using
this.addEventListener
in JS, ensurebubbles: true
andcomposed: true
for cross-component communication.If using the
onpass={fetchValue}
approach, there’s no need forbubbles
andcomposed
unless you expect other components (not just the parent) to handle the event.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744831698a4596123.html
评论列表(0条)