LWC: Create, Dispatch, Handle Event
我们可以在LWC中creat以及dispatch event.
可以使用CustomEvent() constructor来create一个event, 使用EventTarget.dispatchEvent() method来dispatch一个event.
当为event命名的时候,要注意的几点:
1. 不能有大写字母
2. 不能有空格
3. 可以使用下划线来分割单词
Event name的前面尽量不要有on, 因为关联它的event handler name必须以on开头,这样会造成连续出现两个on, 令人困惑。
例如:
<template>
<lightning-layout>
<lightning-layout-item>
<lightning-button label="Close" onclick={closeHandler}></lightning-button>
</lightning-layout-item>
</lightning-layout>
</template>
import { LightningElement } from 'lwc';
export default class Test extends LightningElement {
closeHandler() {
this.dispatchEvent(new CustomEvent('close', {
bubbles: true,
composed: true
}));
}
}
这样的一段代码在点击button的时候,会dispatch一个Event. 我们可以将它放入任何component中,parent component可以监听这个event并且根据自身需求进行处理。
例如:
<template>
<lightning-card title="EventSimple">
<div class="slds-m-around_medium">
<c-test onclose={closeHandler}></c-test>
</div>
</lightning-card>
</template>
import { LightningElement } from 'lwc';
export default class EventSimple extends LightningElement {
test = 'unClose';
closeHandler() {
this.test= 'close';
}
}
也可以添加到aura component中:
<aura:component implements="lightning:isUrlAddressable" access="global">
<c:test onclose="{!c.closeHandler}"/>
<lightning:navigation aura:id="navigateServiceComponent" />
</aura:component>
({
closeHandler : function(component, event, helper) {
// do something
}
})
如果想将数据传递给接收event的component, 可以在CustomEvent() constructor中设置一个detail property.
例如:
<template>
<a href="#" onclick={selectHandler}>
<lightning-layout vertical-align="center">
<lightning-layout-item padding="around-small">
<p>{contact.Name}</p>
</lightning-layout-item>
</lightning-layout>
</a>
</template>
import { LightningElement, api } from 'lwc';
export default class ContactListItem extends LightningElement {
@api contact;
selectHandler(event) {
// Prevents the anchor element from navigating to a URL.
event.preventDefault();
// Creates the event with the contact ID data.
const selectedEvent = new CustomEvent('selected', {
detail: this.contact.Id,
bubbles: true,
composed: true
});
// Dispatches the event.
this.dispatchEvent(selectedEvent);
}
}
接收的component:
<template>
<lightning-card title="EventSimple">
<div class="slds-m-around_medium">
<c-contact-list-item key={contact.Id} contact={contact} onselected={contactSelected}></c-contact-list-item>
</div>
</lightning-card>
</template>
import { LightningElement, wire } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
export default class EventWithData extends LightningElement {
selectedContact;
@wire(getContactList) contacts;
contactSelected(event) {
const contactId = event.detail;
this.selectedContact = this.contacts.data.find(contact => contact.Id === contactId);
}
get listIsNotEmpty() {
return this.contacts && Array.isArray(this.contacts.data) && this.contacts.data.length > 0;
}
}
如果我们创建event的时候把bubbles设置为false以及composed设置为false, 则event既不能通过DOM冒泡,也不能跨越shadow boundary。我们就只能在parent component中以编程的形式设置一个Event Listener来处理它, 例如:
import { LightningElement } from 'lwc';
export default class Parent extends LightningElement {
constructor() {
super();
this.template.addEventListener('notification', this.handleNotification);
}
handleNotification = () => {};
}
如果想要移除掉event listener, 可以在disconnectedCallback中进行设置。
如果把bubbles设置为true, composed设置为false, 则event可以通过DOM冒泡,但是不能跨越shadow boundary
使用这种配置,有两种用例:
1. Create an internal event
// myComponent.js
this.template.querySelector('div')
.dispatchEvent(
new CustomEvent('notify', { bubbles: true })
);
该evnet只能在myComponent.js中执行。
2. Send an event to a component’s grandparent
例如目前component hierarchy从hild到grandparent依次是contact-list-item-bubbling -> lightning-layout-item -> c-event-bubbling
contact-list-item-bubbling上dispatch了一个custom event, event listener: "oncontactselect"在parernt lightning-layout-item上,event是在grandparent c-event-bubbling上处理。
事例代码:https://github.com/trailheadapps/lwc-recipes/tree/main/force-app/main/default/lwc
如果把bubbles设置为true, composed设置为ture, 则event既可以通过DOM冒泡,也可以跨越shadow boundary