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

原文地址:https://www.cnblogs.com/clsriz/p/15021358.html