适用于Aura开发人员的Lightning Web Components 与Event通信

学习目标

完成本单元后,您将能够:

  • 描述两种编程模型在事件上的差异。
  • 将事件从Lightning Web组件发送到Aura组件。

单独隔离的组件可能很有用,但是当组件开始相互交谈时,真正的应用程序魔术就会发生。这就是事件的源头。使用事件在组件之间进行通信是Web标准,而事件对于Aura组件和Lightning Web组件中的通信都是至关重要的。

组件事件成为DOM事件

将Aura组件中的组件事件迁移到Lightning Web组件中的Web标准DOM事件。如果您熟悉DOM事件,则会在Lightning Web组件中注意到相同的传播行为。

创建和发送事件

代替专有 事件 Aura组件中的对象,请使用 事件 要么 CustomEvent标准DOM接口。我们强烈建议您使用CustomEvent界面,因为这样可以提供更一致的体验。该框架可能需要修补事件的属性和方法,以规范浏览器之间的实现,并使用CustomEvent保证您的组件被覆盖。Internet Explorer不支持CustomEvent 接口本身,但Lightning Web组件模型增加了对此的支持。

Lightning Web组件中没有等效的 <aura:registerEvent>在Aura组件标记中标记,以注册组件可以触发事件。由于使用了标准的DOM事件,因此不需要额外的仪式。

代替 event.fire() 在Aura组件中,使用标准DOM方法, this.dispatchEvent(myEvent),在Lightning Web组件中。

这是在广告素材中创建和分配(触发)事件的示例 propertyTile 闪电网络组件。

export default class PropertyTile extends LightningElement {
    @api property;
    propertySelected() {
        const selectedEvent = new CustomEvent('selected', {
            detail: this.property.Id,
        });
        this.dispatchEvent(selectedEvent);
    }
}

中的第一个参数 CustomEvent() 构造函数将事件的名称设置为 已选

第二个参数是配置事件行为的对象。在此对象中,我们将详情,这是事件的数据有效负载。处理组件可以读取数据。在这种情况下,我们通过了this.property.Id 值。

处理事件

Aura组件使用 <光环:处理程序>在标记中标记以定义处理程序。另外,一个组件可以在其标记中引用另一个组件时声明一个处理程序动作。

此光环组件使用 c:孩子 在其标记中并声明一个 handleNotification 通知事件的处理程序 c:孩子 火灾。

<c:child notification="{!c.handleNotification}"/>

Lightning Web组件可以类似地具有声明性处理程序。声明处理程序中的事件名称以前缀

<c-child onnotification={handleNotification}></c-child>

的 handleNotification 事件处理函数在组件的JavaScript文件中定义。

在Lightning Web组件中,您还可以使用标准程序以编程方式设置处理程序 addEventListener() 组件的JavaScript文件中的方法。

让我们看看DreamHouse应用程序如何处理在 propertyTile闪电网络组件。的propertyTileList Lightning Web组件在其HTML文件中处理此事件。

<template for:each={properties} for:item="property">
    <c-property-tile property={property} key={property.Id} onselected={onPropertySelected}></c-property-tile>
</template>

的 已选 事件名称以开头  在由配置的声明处理程序中 onselected = {onPropertySelected}

的 onPropertySelected事件处理程序函数在propertyTileList.js中定义。

onPropertySelected(event) {
    pubsub.fire('propertySelected', event.detail);
}

让您回想起我们开除 已选 事件发生 propertyTile。的CustomEvent() 构造函数集 详情 至 this.property.Id。处理程序通过访问以下事件来解压缩事件数据事件细节。在此示例中,我们获得事件细节

我们解释发生了什么事 pubsub.fire() 接下来我们来看应用程序事件。

应用程序事件成为发布-订阅模式

将Aura组件中的应用程序事件迁移到Lightning Web组件中的发布-订阅(发布-订阅)模式。在发布-订阅模式中,一个组件发布一个事件,其他组件订阅以接收和处理该事件。订阅该事件的每个组件都会接收该事件。

标准DOM事件应该始终是您选择事件的首选,因为它们只会沿安全壳层次结构传播,从而使行为更加可预测。应用程序事件在复杂的应用程序中可能会出现问题,因为任何组件都可以处理该事件。由于组件的意外耦合,这种模式可能导致难以维护的代码。但是,有时您需要包含层次结构中的同级组件进行通信。Lightning页面或Lightning App Builder中使用的不相关组件是需要通信的同级组件的示例。在这些情况下,pub-sub模式是必经之路。

DreamHouse应用程序使用pubsub.js模块。随时复制pubsub 模块并在您的代码中使用它。

的 pubsub 模块导出三种方法。

寄存器
注册事件的回调。
取消注册
注销事件的回调。
向侦听器触发一个事件。

将事件发送到封闭的Aura组件

闪电Web组件调度DOM事件。封闭的Aura组件可以监听这些事件,就像封闭的Lightning Web组件一样。封闭的Aura组件可以捕获事件并进行处理。(可选)Aura组件可以触发Aura事件,以与其他Aura组件或与应用程序容器进行通信。

当您要支持Aura组件中使用但Lightning Web组件当前不支持的事件或接口时,此技术很有用。

以下示例说明了此技术。此Lightning Web组件触发自定义 通知 JavaScript文件中的事件。

// catchAndRelease.js
import { LightningElement } from 'lwc';
export default class CatchAndRelease extends LightningElement {
    /**
     * Handler for 'Fire My Toast' button.
     * @param {Event} evt click event.
     */
    handleFireMyToast(evt) {
        const eventName = 'notification';
        const event = new CustomEvent(eventName, {
            detail: { message: 'See you on the other side.' }
        });
        this.dispatchEvent(event);
    }
}

封闭的Aura组件包装器为自定义事件添加了处理程序。请注意,事件处理程序通知,将事件名称与 以它为前缀。即使用通知 处理名为 通知

<!-- catchAndReleaseWrapper.cmp -->
<aura:component implements="force:appHostable">
    <c:catchAndRelease onnotification="{!c.handleCustomEvent}"/>
</aura:component>

注意

注意

您只能指定一个 通知 DOM事件冒泡到的第一个Aura组件中的处理程序。

的 handleCustomEvent 在控制器的功能 catchAndReleaseWrapper Aura组件处理事件。

// catchAndReleaseWrapperController.js
({
    handleCustomEvent: function(cmp, evt) {
        // Get details from the DOM event fired by the Lightning web component
        var msg = evt.getParam('message') || '';
    }
})

Lightning Web组件调度的通知事件设置事件详细信息。

detail: { message: 'See you on the other side.' }

处理事件的Aura组件使用以下命令访问事件数据 evt.getParam(’message’)

您可以根据需要处理事件。您可以选择触发一个新的Aura事件,以与其他Aura组件进行通信。

适用于Aura开发人员的Lightning Web Components – 组成组件

学习目标

完成本单元后,您将能够:

  • 组成组件。
  • 使用插槽。
  • 列出两种编程模型的数据绑定行为之间的差异。

您可以在另一个组件的主体内添加组件。这种组件组成使您可以从更简单的构建块组件中构建复杂的组件。

在大型应用程序中,将应用程序与一组较小的组件组​​合在一起以使代码更易于重用和维护是很有用的。

的 闪电 命名空间包含许多基本组件,例如 闪电按钮,可用于构建组件。有关更多详细信息,请参见组件库

了解组件关系

让我们从一个简单的示例开始,然后定义一些我们用于组成组件的术语。讨论似乎是不必要的转移,但与其他开发人员交谈时保持一致的术语很重要。

<!-- owner.html -->
<template>
    <c-child first-name="Moonbeam"></c-child>
<template>

该HTML文件使用 <c-child>,指的是 儿童 组件中的 C命名空间。如果尚未为组织设置名称空间前缀,请使用默认名称空间C 引用您创建的组件时。

所有者
所有者是拥有模板的组件。在此示例中,所有者是c所有者组件。所有者控制它包含的所有组成组件。所有者可以:

  • 在组成的组件上设置公共属性。
  • 在组成的组件上调用公共方法。
  • 侦听由组成组件触发的任何事件。
父母与子女
当一个组件包含另一个组件(该组件又可以包含其他组件)时,我们具有一个包含层次结构。在文档中,有时我们讨论父组件和子组件。父组件包含子组件。父组件可以是所有者,也可以是所有者模板的一部分的容器组件。
在这个例子中 c-父容器 是容器组件,因为它包含 小孩。的c-父容器 组件不是所有者,因为它位于所有者组件的模板中, 业主

<!-- owner.html -->
<template>
    <c-parent-container>
        <c-child first-name="Moonbeam"></c-child>
    </c-parent-container>
<template>

梦之屋的例子

让我们看一个组成组件的例子。的PropertyTileList 光环组件包含 PropertyTile 零件。

<aura:component>
    ...
    <div class="slds-card">
        <lightning:layout horizontalAlign="center" multipleRows="true">
            <aura:iteration items="{!v.properties}" var="property">
                <lightning:layoutItem padding="around-small" size="12" smallDeviceSize="6" mediumDeviceSize="4" largeDeviceSize="3">
                    <c:PropertyTile property="{#property}"/>
                </lightning:layoutItem>    
            </aura:iteration>
        </lightning:layout>
    </div>
    
</aura:component>

的 PropertyTile 组件具有称为的属性 属性。不要被那个名字分散注意力。DreamHouse是一个房地产应用程序,因此我们在这里谈论房地产属性而不是JavaScript属性!

这是HTML的 propertyTileList 闪电网络组件:

<template>
    <div class="slds-card tile-list">
        <template for:each={filteredProperties} for:item="property">
            <c-property-tile property={property} key={property.Id}></c-property-tile>
        </template>
    </div>
</template>

对于这两种编程模型,标记看起来相似,除了用于引用组成的组件的语法外。前面我们看到了Aura模型和Lightning Web组件模型如何分别具有不同的语法来引用标记中的组件。

  • 在Aura组件中,我们使用 c:PropertyTile
  • 在Lightning Web组件中,我们使用 房地产。破折号分隔了命名空间,C,来自组件名称。骆驼案propertyTile 闪电Web组件被称为 物业平铺 在包含它的另一个Lightning Web组件的HTML文件中。

Lightning Web组件包含Lightning Web组件

让我们看一下包含两个Lightning Web组件lwcContainerComponent和lwcComponent的组成。

<!-- lwcContainerComponent.html -->
<template>
    <c-lwc-component></c-lwc-component>
</template>

要使用Lightning Web组件, lwcComponent,在另一个Lightning Web组件中:

  • 使用破折号分隔命名空间, C,来自组件名称。
  • 更改骆驼案的名称, lwcComponent,以kebab案例(破折号)为参考, LWC组件。为了与Web组件标准保持一致,我们使用破折号分隔的参考。
  • HTML规范要求自定义元素的标签不能自动关闭。自闭合标签以/>。Lightning Web组件本质上是一个自定义元素。因此,您需要打开和关闭标签以供组件参考:
    <c-lwc-component></c-lwc-component>

Aura组件包含一个闪电Web组件

现在,让我们看一下Aura组件auraWrapper,其中包含Lightning Web组件lwcContainerComponent。

<!-- auraWrapper.cmp -->
<aura:component>
    <c:lwcContainerComponent />
</aura:component>

要使用Lightning Web组件, lwcContainerComponent 在光环组件中:

  • 使用冒号分隔命名空间, C,来自组件名称。
  • 使用骆驼箱组件名称, lwcContainerComponent
  • Aura标记中允许使用自闭合标签,因此我们使用 <c:lwcContainerComponent />

刻面成为插槽

在Aura中,构面是任何类型的属性Aura.Component []。这只是您可以为属性设置一组组件的一种奇特的方式。用更不用说的话,可以将构面视为三明治。您可以根据需要将尽可能多的配料(成分)填充到三明治(构面)中。

例如,每个Aura组件都继承了一个 身体 属性,这是一个方面。构面的概念很重要,因为它使您可以设计具有属性的组件,该属性是父组件可以设置的标记的占位符。

闪电Web组件使用插槽代替刻面。插槽是Web组件规范的一部分

这是一个Aura组件的示例,其中包含一个 标头 方面和 身体 默认情况下,每个组件都有。

<aura:component>
    <aura:attribute name="header" type="Aura.Component[]"/>
    <div>
        <span>{!v.header}</span><br/>
        <span>{!v.body}</span>
    </div>
</aura:component>

类似的Lightning Web组件如下所示。

<template>
    <div>
        <slot name="header"></slot><br/>
        <slot></slot>
    </div>
</template>

插槽名为 标头 取代 标头方面。未命名的插槽取代了身体 方面。

您可以在《Lightning Web Components开发人员指南》中深入了解。

还有其他方面需要考虑的方面吗?

是的,我很高兴你问!请记住,Lightning Web组件不能包含Aura组件。如果要迁移包含构面的Aura组件,则还必须将要填充的所有子组件都迁移到构面中。这样,您可以确保永远不要将Aura组件放入Lightning Web组件中。

数据绑定差异

在标记中添加组件时,可以根据所有者组件的属性值在子组件中初始化公共属性值。两种编程模型的数据绑定行为是不同的。

Aura组件数据绑定

Aura组件可以使用两种形式的表达式语法进行数据绑定: {!expr} 要么 {#expr}。在这里我们将不讨论其中的差异,但让我们看一个简单的示例。

<!-- owner.cmp -->
<aura:component>
    <aura:attribute name="fName" type="String" />
    <c:child firstName="{!v.fName}"/>
</aura:component>

所有者组件传递其值 名称 属性添加到子组件中,这将导致两个组件之间的数据绑定(也称为值绑定)。

在Aura组件中,此数据绑定是两种方法。的变化名称 属性传递到子组件的 名字 属性,以及 名字 子组件中的属性传递回 名称所有者组件的属性。这种双向数据绑定对于性能而言可能是昂贵的,并且由于数据更改的传播而可能创建难以调试的错误,尤其是在您具有深层嵌套的组件的情况下。

Lightning Web组件数据绑定

在Lightning Web组件中,属性值的数据绑定是一种方法。如果属性值在所有者组件中更改,则更新后的值将传播到子组件。反之则不成立。

让我们看一个简单的数据绑定示例。

<!-- owner.html -->
<template>
    <c-child first-name={fName}></child>
</template>

数据绑定行为在Lightning Web组件中故意更简单且更可预测。子组件必须将从所有者组件传递的所有属性值都视为只读。如果子组件更改了从所有者组件传递的值,则会在浏览器控制台中看到错误。

为了触发所有者组件提供的属性值的突变,子组件可以将事件发送给父组件。如果父级拥有数据,则父级可以更改属性值,该属性值将通过单向数据绑定向下传播到子级组件。

适用于Aura开发人员的Lightning Web Components – 组成组件

学习目标

完成本单元后,您将能够:

  • 组成组件。
  • 使用插槽。
  • 列出两种编程模型的数据绑定行为之间的差异。

您可以在另一个组件的主体内添加组件。这种组件组成使您可以从更简单的构建块组件中构建复杂的组件。

在大型应用程序中,将应用程序与一组较小的组件组​​合在一起以使代码更易于重用和维护是很有用的。

的 闪电 命名空间包含许多基本组件,例如 闪电按钮,可用于构建组件。有关更多详细信息,请参见组件库

了解组件关系

让我们从一个简单的示例开始,然后定义一些我们用于组成组件的术语。讨论似乎是不必要的转移,但与其他开发人员交谈时保持一致的术语很重要。

<!-- owner.html -->
<template>
    <c-child first-name="Moonbeam"></c-child>
<template>

该HTML文件使用 <c-child>,指的是 儿童 组件中的 C命名空间。如果尚未为组织设置名称空间前缀,请使用默认名称空间C 引用您创建的组件时。

所有者
所有者是拥有模板的组件。在此示例中,所有者是c所有者组件。所有者控制它包含的所有组成组件。所有者可以:

  • 在组成的组件上设置公共属性。
  • 在组成的组件上调用公共方法。
  • 侦听由组成组件触发的任何事件。
父母与子女
当一个组件包含另一个组件(该组件又可以包含其他组件)时,我们具有一个包含层次结构。在文档中,有时我们讨论父组件和子组件。父组件包含子组件。父组件可以是所有者,也可以是所有者模板的一部分的容器组件。
在这个例子中 c-父容器 是容器组件,因为它包含 小孩。的c-父容器 组件不是所有者,因为它位于所有者组件的模板中, 业主

<!-- owner.html -->
<template>
    <c-parent-container>
        <c-child first-name="Moonbeam"></c-child>
    </c-parent-container>
<template>

梦之屋的例子

让我们看一个组成组件的例子。的PropertyTileList 光环组件包含 PropertyTile 零件。

<aura:component>
    ...
    <div class="slds-card">
        <lightning:layout horizontalAlign="center" multipleRows="true">
            <aura:iteration items="{!v.properties}" var="property">
                <lightning:layoutItem padding="around-small" size="12" smallDeviceSize="6" mediumDeviceSize="4" largeDeviceSize="3">
                    <c:PropertyTile property="{#property}"/>
                </lightning:layoutItem>    
            </aura:iteration>
        </lightning:layout>
    </div>
    
</aura:component>

的 PropertyTile 组件具有称为的属性 属性。不要被那个名字分散注意力。DreamHouse是一个房地产应用程序,因此我们在这里谈论房地产属性而不是JavaScript属性!

这是HTML的 propertyTileList 闪电网络组件:

<template>
    <div class="slds-card tile-list">
        <template for:each={filteredProperties} for:item="property">
            <c-property-tile property={property} key={property.Id}></c-property-tile>
        </template>
    </div>
</template>

对于这两种编程模型,标记看起来相似,除了用于引用组成的组件的语法外。前面我们看到了Aura模型和Lightning Web组件模型如何分别具有不同的语法来引用标记中的组件。

  • 在Aura组件中,我们使用 c:PropertyTile
  • 在Lightning Web组件中,我们使用 房地产。破折号分隔了命名空间,C,来自组件名称。骆驼案propertyTile 闪电Web组件被称为 物业平铺 在包含它的另一个Lightning Web组件的HTML文件中。

Lightning Web组件包含Lightning Web组件

让我们看一下包含两个Lightning Web组件lwcContainerComponent和lwcComponent的组成。

<!-- lwcContainerComponent.html -->
<template>
    <c-lwc-component></c-lwc-component>
</template>

要使用Lightning Web组件, lwcComponent,在另一个Lightning Web组件中:

  • 使用破折号分隔命名空间, C,来自组件名称。
  • 更改骆驼案的名称, lwcComponent,以kebab案例(破折号)为参考, LWC组件。为了与Web组件标准保持一致,我们使用破折号分隔的参考。
  • HTML规范要求自定义元素的标签不能自动关闭。自闭合标签以/>。Lightning Web组件本质上是一个自定义元素。因此,您需要打开和关闭标签以供组件参考:
    <c-lwc-component></c-lwc-component>

Aura组件包含一个闪电Web组件

现在,让我们看一下Aura组件auraWrapper,其中包含Lightning Web组件lwcContainerComponent。

<!-- auraWrapper.cmp -->
<aura:component>
    <c:lwcContainerComponent />
</aura:component>

要使用Lightning Web组件, lwcContainerComponent 在光环组件中:

  • 使用冒号分隔命名空间, C,来自组件名称。
  • 使用骆驼箱组件名称, lwcContainerComponent
  • Aura标记中允许使用自闭合标签,因此我们使用 <c:lwcContainerComponent />

刻面成为插槽

在Aura中,构面是任何类型的属性Aura.Component []。这只是您可以为属性设置一组组件的一种奇特的方式。用更不用说的话,可以将构面视为三明治。您可以根据需要将尽可能多的配料(成分)填充到三明治(构面)中。

例如,每个Aura组件都继承了一个 身体 属性,这是一个方面。构面的概念很重要,因为它使您可以设计具有属性的组件,该属性是父组件可以设置的标记的占位符。

闪电Web组件使用插槽代替刻面。插槽是Web组件规范的一部分

这是一个Aura组件的示例,其中包含一个 标头 方面和 身体 默认情况下,每个组件都有。

<aura:component>
    <aura:attribute name="header" type="Aura.Component[]"/>
    <div>
        <span>{!v.header}</span><br/>
        <span>{!v.body}</span>
    </div>
</aura:component>

类似的Lightning Web组件如下所示。

<template>
    <div>
        <slot name="header"></slot><br/>
        <slot></slot>
    </div>
</template>

插槽名为 标头 取代 标头方面。未命名的插槽取代了身体 方面。

您可以在《Lightning Web Components开发人员指南》中深入了解。

还有其他方面需要考虑的方面吗?

是的,我很高兴你问!请记住,Lightning Web组件不能包含Aura组件。如果要迁移包含构面的Aura组件,则还必须将要填充的所有子组件都迁移到构面中。这样,您可以确保永远不要将Aura组件放入Lightning Web组件中。

数据绑定差异

在标记中添加组件时,可以根据所有者组件的属性值在子组件中初始化公共属性值。两种编程模型的数据绑定行为是不同的。

Aura组件数据绑定

Aura组件可以使用两种形式的表达式语法进行数据绑定: {!expr} 要么 {#expr}。在这里我们将不讨论其中的差异,但让我们看一个简单的示例。

<!-- owner.cmp -->
<aura:component>
    <aura:attribute name="fName" type="String" />
    <c:child firstName="{!v.fName}"/>
</aura:component>

所有者组件传递其值 名称 属性添加到子组件中,这将导致两个组件之间的数据绑定(也称为值绑定)。

在Aura组件中,此数据绑定是两种方法。的变化名称 属性传递到子组件的 名字 属性,以及 名字 子组件中的属性传递回 名称所有者组件的属性。这种双向数据绑定对于性能而言可能是昂贵的,并且由于数据更改的传播而可能创建难以调试的错误,尤其是在您具有深层嵌套的组件的情况下。

Lightning Web组件数据绑定

在Lightning Web组件中,属性值的数据绑定是一种方法。如果属性值在所有者组件中更改,则更新后的值将传播到子组件。反之则不成立。

让我们看一个简单的数据绑定示例。

<!-- owner.html -->
<template>
    <c-child first-name={fName}></child>
</template>

数据绑定行为在Lightning Web组件中故意更简单且更可预测。子组件必须将从所有者组件传递的所有属性值都视为只读。如果子组件更改了从所有者组件传递的值,则会在浏览器控制台中看到错误。

为了触发所有者组件提供的属性值的突变,子组件可以将事件发送给父组件。如果父级拥有数据,则父级可以更改属性值,该属性值将通过单向数据绑定向下传播到子级组件。

适用于Aura开发人员的Lightning Web Components – 使用Salesforce数据

学习目标

完成本单元后,您将能够:

  • 使用基本组件创建用于处理单个记录的表单。
  • 使用有线服务获取数据。
  • 创建和更新数据。
  • 调用Apex方法。

没有任何数据的组件可能看起来不错,但内部感觉有些空白。在本单元中,我们填补了这一空白,并比较了Aura和Lightning组件如何读写Salesforce数据。

如果您为Aura组件开发了Apex类,则可以在Lightning Web组件中重用Apex。但是,由于在Lightning Web组件中使用数据的替代方法,您可能会发现不再需要Apex。

创建一个表单以处理单个记录

要创建允许用户查看,编辑和创建Salesforce记录的表单,Aura组件和Lightning Web组件都可以在 闪电 命名空间。

这些组件提供表单布局并处理记录的CRUD更改,而无需Apex代码。他们使用Lightning Data Service在各个组件之间缓存和共享记录更新。

Lightning Data Service构建在公共用户界面API之上,但仅支持API的子集。该子集涵盖了许多处理数据的典型用例。

这些组件的行为相同,但是具有命名约定的区别,这与我们之前在Aura组件和Lightning Web组件中看到的一样。

表格功能 灵气成分 闪电网络组件
支持编辑,查看和只读模式 闪电:记录形式 闪电记录形式
只读形式 闪电:recordViewForm 闪电记录视图形式
可编辑表格 闪电:recordEditForm 闪电记录编辑表

在大多数情况下, 闪电记录形式提供了一个很好的起点。它结合并简化了功能闪电记录视图形式 和 闪电记录编辑表

对于需要自定义字段布局和自定义呈现记录数据的更高级用例,请使用 闪电记录视图形式 和 闪电记录编辑表

这是一个例子 经纪人详细信息 灵气成分。

<lightning:recordForm
  objectApiName="Broker__c"
  recordId="{!v.property.Broker__c}"
  fields="{!v.brokerFields}"
  columns="2"/>

这是等效的HTML brokerCard 闪电网络组件。

<lightning-record-form
  object-api-name="Broker__c" 
  record-id={brokerId}
  fields={brokerFields} 
  columns="2">
</lightning-record-form>

自定义用户界面以处理单个记录

需要对UI进行更多控制的Aura组件 闪电:记录形式 和朋友提供可以使用 <force:recordData> 在标记中使用自己的自定义UI标记代码。

的 物业摘要 光环组件用途 <force:recordData> 在其标记中。

<force:recordData aura:id="service"
      recordId="{!v.recordId}"
      targetFields="{!v.property}"
      fields="['Id',
              'Thumbnail__c',
              'Address__c',
              'City__c',
              'State__c',
              'Zip__c',
              'Price__c',
              'Beds__c',
              'Baths__c',
              'Broker__r.Id',
              'Broker__r.Name',
              'Broker__r.Title__c',
              'Broker__r.Mobile_Phone__c',
              'Broker__r.Email__c',
              'Broker__r.Picture__c']" />

代替 <force:recordData>,Lightning Web组件有几种使用Lightning Data Service的技术,但是根据您是读取还是写入数据而有所不同。仅在以下情况下才考虑使用Wire Service和JavaScript API方法: 闪电记录*形式 组件不符合您的要求。

使用电汇服务获取数据

要读取Salesforce数据,Lightning Web组件使用基于Lightning Data Service构建的反应式线路服务。组件使用@线 在他们的JavaScript类中从其中的一个有线适配器读取数据 闪电/ ui * api命名空间。有关Salesforce提供的电线适配器的列表,请参阅本单元的“资源”部分。您不能编写自己的自定义线适配器。

我们之所以将有线服务称为响应式服务,部分原因是它支持响应式变量,该变量以$开头。如果电抗变量发生变化,则电汇服务将提供新数据。我们说“设置”而不是“请求”或“获取”,因为有线适配器而不是组件控制何时提供数据。

这是propertySummary.js中使用的示例@线 检索记录。

import { LightningElement, api, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Property__c.Name';
import PICTURE_FIELD from '@salesforce/schema/Property__c.Picture__c';
export default class PropertySummary extends LightningElement {
    @api recordId;
    propertyName;
    pictureURL;
    @wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD, PICTURE_FIELD] })
    wiredRecord({ error, data }) {
        if (data) {
            this.propertyName = getFieldValue(data, NAME_FIELD);
            this.pictureURL = getFieldValue(data, PICTURE_FIELD);
        } else if (error) {
            // Handle error. Details in error.message.
        }
    }
}

该代码导入 getRecord 电线适配器来自 lightning / uiRecordApi

当您使用 ui * Api线适配器,我们强烈建议导入对对象和字段的引用。导入对对象和字段的引用可确保您的代码正常工作,因为Salesforce会验证对象和字段是否存在。这行代码导入了对名称 中的字段 属性 自定义对象。

import NAME_FIELD from '@salesforce/schema/Property__c.Name';

的 @api 装饰使 recordId财产公开。包含的父组件 属性摘要 设置的值 记录编号 HTML文件中的属性。

因为 $ recordId 前面有一个 $,当其值更改时,有线服务将获取新数据并将其提供给组件。提供新数据时,将调用有线功能。该过程将更新属性,从而导致重新渲染。

的 有线录音函数从有线服务接收数据流。记录数据返回到数据论据。任何错误都将返回给错误 论据。

使用JavaScript API方法写入数据

的 createRecordJavaScript API创建一条记录。您也可以使用updateRecord 要么 deleteRecord。我们仍在使用Lightning Data Service,因此不需要Apex。

重要

不要使用 @线创建,更新或删除记录。有线服务将控制流委托给Lightning Web Components引擎。委派控制对于读取操作非常有用,但是对于创建,更新和删除操作却不是很好。作为开发人员,您希望完全控制更改数据的操作。这就是为什么您使用JavaScript API(而不是有线服务)执行创建,更新和删除操作的原因。

这是一个 ldsCreateRecord 使用的Lightning Web组件 createRecord 创建一个帐户。

import { LightningElement } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { createRecord } from 'lightning/uiRecordApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';
export default class LdsCreateRecord extends LightningElement {
    accountId;
    name;
    onNameChange(event) {
        this.name = event.target.value;
    }
    createAccount() {
        const recordInput = {
            apiName: ACCOUNT_OBJECT.objectApiName,
            fields: { 
                [NAME_FIELD.fieldApiName]: this.name, 
            }
        };
        createRecord(recordInput)
            .then(account => {
                this.accountId = account.id;
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Success',
                        message: 'Account created',
                        variant: 'success',
                    }),
                );
            })
            .catch(error => {
                // Handle error. Details in error.message.
            });
    }
}

createRecord 返回一个 诺言成功解决创建的记录的对象。有关JavaScript API的更多信息,请参见本单元末尾的参考资料。

的HTML文件 ldsCreateRecord 包括一个调用的按钮 创建帐号()在JavaScript文件中。帐户名称设置在雷电输入 零件。

<template>
    <lightning-card title="LdsCreateRecord" icon-name="standard:record">
        <div class="slds-m-around_medium">
            <lightning-input label="Id" disabled value={accountId}></lightning-input>
            <lightning-input label="Name" onchange={onNameChange} class="slds-m-bottom_x-small"></lightning-input>
            <lightning-button label="Create Account" variant="brand" onclick={createAccount}></lightning-button>
        </div>
    </lightning-card>
</template>

使用Apex进行自定义数据访问

我们已经研究了一些使用Lightning Data Service处理数据的技术。这些技术通常意味着更少的代码,因为您不需要任何Apex。但是,如果您已经具有为Aura组件开发的Apex代码,则可以在Lightning Web组件中重复使用它。或者,如果需要SOQL查询来进行自定义数据访问,则必须使用Apex方法。

要从Aura组件访问Apex控制器,请从JavaScript控制器或帮助器进行调用。这是物业轮播 光环组件调用 getPictures() Apex方法。

({
    loadPictures : function(component) {
        var propertyId = component.get("v.recordId");
        component.set("v.files", []);
        if (!propertyId) {
            return;
        }
        var action = component.get("c.getPictures");
        action.setParams({
            "propertyId": propertyId,
        });
        action.setCallback(this, function (response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var files = response.getReturnValue();
                component.set("v.files", files);
            }
            else if (state === "INCOMPLETE") {
                // handle incomplete state
            }
            else if (state === "ERROR") {
                // handle error state
            }
        });
        $A.enqueueAction(action);
    }
})

任何访问Salesforce数据的Aura组件都具有类似的样板。对于Lightning Web组件,访问Apex方法的语法不同。

闪电Web组件可以从Apex类导入方法。导入的方法是组件可以通过声明方式调用的函数@线 或直接在代码中。

将Apex方法公开给闪电Web组件

要将Apex方法公开给Lightning Web组件,该方法必须为 静态的 还有 全球 要么 上市。注释方法@AuraEnabled。这些要求与在Aura组件中使用Apex方法相同。的@AuraEnabled注解意味着您可以从Aura组件或Lightning Web组件调用方法。即使 @AuraEnabled 对于Lightning Web组件来说似乎是意外的,使用批注意味着您可以在两个编程模型中使用相同的Apex代码。

使用有线服务调用Apex方法

如果Apex方法是可缓存的(它不变异数据),则可以通过有线服务从组件调用它。您必须使用以下方法注释方法@AuraEnabled(cacheable = true)

注意

别 @线 创建,更新或删除数据的Apex方法。

让我们看一个 MyAccountController Apex控制器带有一个 getAccounts() 方法。

// MyAccountController.cls
public with sharing class MyAccountController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAccounts() {
        return [SELECT Id, Name FROM Account
            WHERE AnnualRevenue > 1000000];
    }
}

此JavaScript代码称为Apex getAccounts() 使用有线服务的方法。

import { LightningElement, wire } from 'lwc';
import getAccounts from '@salesforce/apex/MyAccountController.getAccounts';
export default class HelloApexAccounts extends LightningElement {
    accounts=[];
    @wire(getAccounts, {})
    wiredAccounts({ error, data }) {
        if (error) {
            this.error = error;
        } else if (data) {
            this.accounts = data;
        }
    }
}

请注意导入语句的语法 getAccounts

import getAccounts from '@salesforce/apex/MyAccountController.getAccounts';
  • MyAccountController 是Apex类的名称
  • getAccounts 是个 @AuraEnabled 我们导入的方法

直接调用Apex方法

如果Apex方法更改(创建,更新或删除)数据,因此不可缓存,则必须直接在代码中调用该方法。

这是一个调用Apex的Lightning Web组件 getContactList() 方法。

import { LightningElement } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
export default class ApexContactList extends LightningElement {
    contacts;
    getContacts() {
        getContactList()
            .then(result => {
                this.contacts = result;
            })
            .catch(error => {
                // Handle error. Details in error.message.
            });
    }
}

import语句看起来与有线服务示例相同。但是,调用该方法的语法没有@线注解。代替, getContactList() 返回一个 诺言 通过联系人列表成功解决的对象。

使用外部API

在Lightning Web组件中使用外部API类似于Aura组件。默认情况下,您无法从Lightning Web组件中的JavaScript代码调用第三方API。将远程站点添加为CSP受信任站点,以允许JavaScript组件代码从该站点的域加载资产并向该域的域发出API请求。

Aura组件和Lightning Web组件在运行来自第三方站点的JavaScript代码方面具有相同的限制。要使用第三方库,您必须将库作为静态资源上载。

适用于Aura开发人员的Lightning Web Components – 迁移JavaScript

学习目标

完成本单元后,您将能够:

  • 将JavaScript从Aura组件迁移到Lightning Web组件。
  • 在Aura组件和Lightning Web组件之间共享代码。

使用JavaScript模块

JavaScript是Lightning Web组件的心脏。没有JavaScript,组件就是毫无生气的主要是HTML。当我们看到Aura组件中的属性如何映射到JavaScript属性时,我们可以窥见上一个单元中的Lightning Web组件中的JavaScript文件。现在,我们更深入地研究JavaScript文件。

将JavaScript代码从Aura组件中单独的客户端控制器,帮助程序和渲染器文件迁移到Lightning Web组件中的一个JavaScript文件。

Aura组件中的客户端控制器是对象文字表示形式的JavaScript对象,其中包含名称-值对的映射。好多话。让我们看一下PropertyPaginatorController.js文件中的示例:

({
	previousPage : function(component) {
        var pageChangeEvent = component.getEvent("pagePrevious");
        pageChangeEvent.fire();
	},
    
	nextPage : function(component) {
        var pageChangeEvent = component.getEvent("pageNext");
        pageChangeEvent.fire();
	}
})

Aura组件中JavaScript文件的格式是在将ES6标准(例如JavaScript类和模块)用于功能标准化之前设计的。

Lightning Web组件中的JavaScript文件是ES6模块,因此您使用的是标准JavaScript,而不是Aura组件中使用的专有格式。您编写的JavaScript看起来与您为其他任何现代JavaScript框架编写的JavaScript相似。

这是类似的JavaScript 分页器 闪电网络组件。

import { LightningElement, api } from 'lwc';
export default class Paginator extends LightningElement {
    /** The current page number. */
    @api pageNumber;
    /** The number of items on a page. */
    @api pageSize;
    /** The total number of items in the list. */
    @api totalItemCount;
    previousHandler() {
        this.dispatchEvent(new CustomEvent('previous'));
    }
    nextHandler() {
        this.dispatchEvent(new CustomEvent('next'));
    }
    get currentPageNumber() {
        return this.totalItemCount === 0 ? 0 : this.pageNumber;
    }
    get isFirstPage() {
        return this.pageNumber === 1;
    }
    get isLastPage() {
        return this.pageNumber >= this.totalPages;
    }
    get totalPages() {
        return Math.ceil(this.totalItemCount / this.pageSize);
    }
}

我们不会看每一行代码。主要的收获是Lightning Web组件使用标准的JavaScript模块。这是好事!

在Aura组件和Lightning Web组件之间共享代码

要在Lightning Web组件和Aura组件之间共享JavaScript代码,请将代码放在ES6模块中。两种编程模型都可以访问共享代码。即使您没有将所有代码都移至Lightning Web组件,您仍然可以访问在Aura组件的ES6模块中编写的新功能。

让我们看一个utils.js ES6模块的示例。

/* utils.js */
/**
 * Returns whether provided value is a function
 * @param {*} value - the value to be checked
 * @return {boolean} true if the value is a function, false otherwise
 */
export function isFunction(value) {
    return typeof value === 'function';
}

的 实用程序 模块导出一个 isFunction() 返回提供的参数是否为函数的函数。

这是一个 c-libcaller 使用以下内容的Lightning Web组件 实用程序 模块。

/* libcaller.js */
import { LightningElement } from 'lwc';
// import the library
import { isFunction } from 'c/utils';
export default class LibCaller extends LightningElement {
    result;
    
    checkType() {
        // Call the imported library function
        this.result = isFunction(
            function() {
                console.log('I am a function');
            }
        ); 
    }
}

的 c-libcaller 组件导入 实用程序 模块并调用 isFunction模块导出的函数。论点传递给isFunction 是一个函数,因此结果设置为 真正

现在,让我们看一个libcallerAura.cmp文件,该文件也使用实用程序 模块。

<aura:component>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <p>Aura component calling the utils lib</p>
    <!-- add the lib component -->
    <c:utils aura:id="utils" />
</aura:component>

的 libcaller光环 光环组件包括对 c:工具ES6模块。我们添加了一个光环:id 这样我们就可以在JavaScript代码中获得对该模块的引用。

这是libcallerAuraController.js文件。

({
    doInit: function(cmp) {
        // Call the lib here
        var libCmp = cmp.find('utils');
        var result = libCmp.isFunction(
            function() {
                console.log(" I am a function");
            }
        );
        console.log("Is it a function?: " + result);
    }
})

组件的控制器使用 cmp.find(’utils’) 匹配 光环:id在标记中并获得对该模块的引用。的实用程序 ES6模块导出 isFunction(),由Aura组件调用。论点传递给isFunction() 是一个函数,因此结果设置为 真正

使用第三方JavaScript库

要在Aura组件或Lightning Web组件中使用第三方JavaScript库,必须将库作为静态资源上载。在两种编程模型中,使用静态资源的语法不同。

在Aura组件中,使用 <ltng:require> 在标记中添加标签以加载静态资源。

<ltng:require scripts="{!$Resource.resourceName}"
    afterScriptsLoaded="{!c.afterScriptsLoaded}" />

resourceName是静态资源的名称。的afterScripts已加载 加载脚本并呈现组件后,将调用客户端控制器中的action。

在Lightning Web组件中,使用JavaScript导入静态资源。

import resourceName from '@salesforce/resourceUrl/resourceName';

然后,您使用 loadScript 和 loadStyle 加载第三方库。

有关使用导入的库的详细信息,请参阅《 Lightning Web Components开发人员指南》中的“使用第三方JavaScript库

动态创建组件

在Aura组件中,您可以使用以下方式在JavaScript中动态创建组件: $ A.createComponent()。在Lightning Web组件中没有动态创建组件的等效项。

这个体系结构的决定是有意的。不在Lightning Web组件中复制此模式的主要原因是Aura组件中的模式导致错误和混乱的代码。

Lightning Web组件中更好的替代方法是为您的组件创建多个HTML模板。组件的render()该方法可以根据组件需求切换模板。这种模式更类似于其他JavaScript框架中使用的路由拆分。

重构的机会

迁移JavaScript代码时,请注意,它不是逐行转换。这是重新审视组件设计的好机会。

迁移到新的编程模型就像走一条新路径,将您带到相同的目的地。一路上的视觉和声音(以及您编写的代码)是不同的。

迁移组件也是使用Aura组件中可能未使用的ES6新功能(例如JavaScript模块)的绝佳机会。

在现代JavaScript开发的Trailhead模块为您提供了这些新功能很好的概述。

适用于Aura开发人员的Lightning Web Components – 迁移标记和CSS

学习目标

完成本单元后,您将能够:

  • 将HTML和标记从Aura组件迁移到Lightning Web组件。
  • 将CSS从Aura组件迁移到Lightning Web组件。

梦之屋应用

比较Aura Component和Lightning Web Components编程模型的最佳方法是查看两个模型中编写的相似组件的代码。

我们将研究DreamHouse应用程序中的某些组件,该应用程序是Salesforce开发来展示Lightning组件的相对复杂的应用程序。DreamHouse是一个基于Salesforce平台的房地产业务的示例应用程序。该应用程序使经纪人能够管理其财产,并使买家能够找到他们梦想中的家。

DreamHouse应用程序具有针对Aura组件和Lightning Web组件的单独实现,并且每个组件的完整代码都位于两个不同的GitHub存储库中。在两个版本的应用程序中,功能都不相同,但是有一些组件可用于比较两个编程模型。

GitHub存储库中提供了DreamHouse应用程序的两种实现的代码。

  • DreamHouse Aura组件GitHub存储库
  • DreamHouse Lightning Web组件GitHub存储库

我们将查看Aura组件中的代码片段,并向您展示Aura代码如何映射到Lightning Web组件代码。我们还将向您展示Aura组件概念如何转换为Lightning Web组件,并且我们将重点关注核心片段以说明这些概念。然后,如果您对更多上下文感兴趣,可以探索这些组件。

组件捆绑

对于Aura组件和Lightning Web组件,组件捆绑包文件结构不同。这是文件在两种类型的组件之间的映射方式。

资源资源 光环文件 闪电Web组件文件
标记 sample.cmp sample.html
控制者 sampleController.js sample.js
帮手 sampleHelper.js
渲染器 sampleRenderer.js
的CSS sample.css sample.css
文献资料 sample.auradoc 目前不可用
设计 样本设计 sample.js-meta.xml
SVG sample.svg 包含在HTML文件中或作为静态资源上传

注意

Aura组件中的单独的控制器,助手和渲染器文件映射到Lightning Web组件中的一个JavaScript文件。

Lightning Web组件必须包含HTML文件,JavaScript文件和配置文件。它可以选择包括CSS文件和更多JavaScript文件。

不呈现任何UI的组件(也称为服务组件或库)必须包含JavaScript文件和元数据配置文件。

在本单元中,我们研究HTML和CSS文件。在下一单元中,我们探索JavaScript文件。

Lightning Web组件还具有一个配置文件,该文件定义了该组件的元数据值,包括打算在Lightning App Builder中使用的组件的设计配置。配置文件中包含一些由接口定义的元数据,例如flexipage:availableForRecordHome,在Aura组件中。

迁移标记

Aura组件在.cmp文件中包含标记。该文件以 <光环:组件> 标签,并且可以包含HTML和Aura特定的标签。

Lightning Web组件在.html文件中包含标记。该文件以<模板> 标签,并且可以包含HTML和动态内容的指令。

让我们看看Aura标记如何映射到Lightning Web组件的HTML和JavaScript文件中的内容。

属性成为JavaScript属性

从迁移属性 <光环:属性>将Aura组件的标记(.cmp)中的标签添加到Lightning Web组件的JavaScript文件(.js)中的JavaScript属性。

让我们在标记的属性中查看这些属性 物业摘要灵气成分。您可以在DreamHouse Aura组件GitHub存储库中看到完整的文件。

    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="property" type="Property__c" />

在Lightning Web组件中,我们使用JavaScript属性而不是标记中的属性。让我们看一下propertySummary.js中的属性

import { LightningElement, api } from 'lwc';
export default class PropertySummary extends LightningElement {
    @api recordId;
    property;
        ...
}

的 recordId 和 属性 灵气成分的属性变为 recordId 和 属性 Lightning Web组件中的JavaScript属性。

的 @api 装饰标记 recordId作为公共财产。公共属性是该组件的公共API的一部分,这意味着可以在Lightning App Builder中对其进行设置,也可以由在其标记中使用该组件的父组件来对其进行设置。

基本的Aura表达式成为HTML表达式

将基本表达式从Aura组件中的标记迁移到Lightning Web组件中的HTML表达式。基本表达式的一个示例是对Aura组件中的属性的引用。

例如, PropertyPaginator Aura组件使用基本表达式来显示 , 页数和  属性。

<aura:component >
    <aura:attribute name="page" type="integer"/>
    <aura:attribute name="pages" type="integer"/>
    <aura:attribute name="total" type="integer"/>
    
    <div class="centered">{!v.total} properties • page {!v.page} of {!v.pages}</div>
</aura:component>

这是HTML文件中的等效语法 分页器 闪电网络组件。

<template>
    {totalItemCount} items • page {currentPageNumber} of {totalPages}
</template>

注意

Lightning Web组件的HTML文件中的动态内容没有感叹号或值提供程序(v。) 句法。即使可能会用手指打字,也不要在Lightning Web组件中使用Aura组件中的表达式语法!

HTML引用了 totalItemCountpaginator.js中的属性。的{currentPageNumber} 和 {totalPages} 表达式引用处理程序的吸气剂 pageNumber 和 页面大小 属性。

import { LightningElement, api } from 'lwc';
export default class Paginator extends LightningElement {
    /** The current page number. */
    @api pageNumber;
    /** The number of items on a page. */
    @api pageSize;
    /** The total number of items in the list. */
    @api totalItemCount;
    get currentPageNumber() {
        return this.totalItemCount === 0 ? 0 : this.pageNumber;
    }
    get totalPages() {
        return Math.ceil(this.totalItemCount / this.pageSize);
    }
}

了解条件语句后,我们会尽快处理更复杂的表达式。

Aura条件句成为HTML条件句

迁移 <光环:如果> Aura组件中的标签 如果属实 要么 如果:假 Lightning Web组件的HTML文件中的指令。

这是一些条件标记 经纪人详细信息 灵气成分。

<aura:if isTrue="{!v.property.Broker__c}">
    <lightning:recordForm recordId="{!v.property.Broker__c}"
      objectApiName="Broker__c"
      fields="{!v.brokerFields}" columns="2"/>
</aura:if>

这是类似的HTML brokerCard 闪电网络组件。

<template if:true={property.data}>
    <lightning-record-form object-api-name="Broker__c" 
      record-id={brokerId} fields={brokerFields} 
      columns="2">
    </lightning-record-form>
</template>

注意

Lightning Web组件的HTML文件中的动态内容没有引号, {brokerId}参考。这不是错字!

Lightning Web组件的HTML文件以标准HTML开头 <模板> 标签,并且还可以包含其他 <模板>标签在其体内。在此示例中, <模板> 标签会根据 如果属实 指示。

复杂的Aura表达式成为JavaScript逻辑

我们看到了基本的Aura表达式,例如对属性值的引用,如何变成HTML表达式。将Aura组件中的复杂Aura表达式(例如比较运算或三元运算符)迁移到Lightning Web组件中的JavaScript getter。

Aura组件支持丰富的表达式集,例如 PropertyPaginator Aura组件,它使用 {!v.page> 1}

<aura:if isTrue="{!v.page > 1}">
    <lightning:buttonIcon iconName="utility:left" variant="border" onclick="{!c.previousPage}"/>
</aura:if>

Aura中的表达语言使您可以在标记中包含更多逻辑。不利之处在于,很难对该逻辑进行单元测试,并且该功能只是您在JavaScript中可以执行的操作的一部分。

在Lightning Web组件中,将复杂表达式移动到JavaScript中。现在可以对代码进行单元测试,这使代码更稳定,开发人员更快乐。您还可以使用JavaScript的全部功能来编写逻辑。

这是类似的HTML 分页器 闪电网络组件。

<template if:false={isFirstPage}>
    <lightning-button-icon icon-name="utility:chevronleft" onclick={previousHandler}></lightning-button-icon>
</template>

paginator.js中的getter计算{isFirstPage}健康)状况。例如:

import { LightningElement, api } from 'lwc';
export default class Paginator extends LightningElement {
    /** The current page number. */
    @api pageNumber;
    get isFirstPage() {
        return this.pageNumber === 1;
    }
}

Aura迭代成为HTML迭代

迁移 <光环:迭代> Aura组件中的标签 为:每个 Lightning Web组件的HTML文件中的指令。

这是PropertyTileList.cmp中的Aura语法。

<aura:iteration items="{!v.properties}" var="property">
    <c:PropertyTile property="{#property}"/>
</aura:iteration>

这是类似的HTML propertyTileList 闪电网络组件。

<template for:each={properties.data.records} for:item="property">
    <c-property-tile property={property} key={property.Id} 
      onselected={handlePropertySelected}></c-property-tile>
</template>

Aura初始化程序成为生命周期挂钩

更换 在里面 具有标准JavaScript的Aura组件中的事件处理程序 connectedCallback()Web组件中的方法。的connectedCallback() 将组件插入DOM时会触发生命周期挂钩。生命周期挂钩是回调方法,使您可以在组件生命周期的每个阶段运行代码。

我们使用 在里面 Aura组件中的事件用于在组件构造之后但渲染之前初始化组件。

这是一个 在里面 中的事件处理程序 物业轮播 灵气成分。

<aura:handler name="init" value="{!this}" action="{!c.onInit}" />

的 onInit Aura组件的控制器中的函数执行任何必要的初始化。

在Lightning Web组件中,使用 connectedCallback() 而是在组件的JavaScript文件中。这是propertySummary.js中的示例 。

export default class PropertySummary extends LightningElement {
    ...
    connectedCallback() {
        // initialize component
    }
}

迁移基础组件

还记得Lightning Web组件不能包含Aura组件吗?如果您需要迁移的Aura组件包含Salesforce提供的内置组件,该怎么办?基础闪电组件是Salesforce在闪电名称空间,它们在Aura组件和Lightning Web组件中都可用。在两个编程模型中使用基础Lightning组件时,它们具有不同的语法。

此光环组件使用 闪电:formattedNumber 基本组件。

<aura:component>
    <lightning:formattedNumber value="5000" style="currency"
      currencyCode="USD" />
</aura:component>

将此标记迁移到Lightning Web组件:

  • 更改用于分隔名称空间的冒号(闪电)和组件名称(formattedNumber)。
  • 更改驼峰案例的组件名称(formattedNumber)以短划线分隔的名称(格式化数字)。
  • 更改驼峰案例属性名称(货币代码)以短划线分隔的名称(货币代码)。

这是等效的Lightning Web组件。

<template>
    <lightning-formatted-number value="5000" style="currency"
      currency-code="USD">
    </lightning-formatted-number>
</template>

注意

HTML规范要求自定义元素的标签不能自动关闭。自闭合标签以/>。Lightning Web组件本质上是一个自定义元素。因此,<闪电格式编号> 组件参考包含一个单独的结束语 </ lightning-formatted-number>标签。此要求与允许自动关闭标签的Aura组件不同。

Aura CSS成为标准CSS

闪电Web组件使用标准CSS语法。删除专有这个 Aura组件使用的类。

这是CSS文件的一部分, PropertyTile 灵气成分。

.THIS .lower-third {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    color: #FFF;
    background-color: rgba(0, 0, 0, .3);
    padding: 6px 8px;
}
.THIS .lower-third > p {
    padding: 0;
    margin: 0;
}
.THIS .truncate {
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

类似的CSS propertyTileLightning Web组件改用标准CSS。的这个 关键字特定于Aura,在Lightning Web组件中未使用。

.lower-third {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    color: #FFF;
    background-color: rgba(0, 0, 0, .3);
    padding: 6px 8px;
}
.lower-third > p {
    padding: 0;
    margin: 0;
}
.truncate {
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

带有闪电设计系统的样式组件

Lightning Experience或Salesforce移动应用程序中的自定义组件可以使用Lightning Design System,而无需任何导入语句或静态资源。将Lightning Design System CSS类分配给HTML元素,就可以了。

闪电Web组件继承Aura组件样式

Aura组件样式可级联到它们包含的任何Lightning Web组件。

但是,Lightning Web组件的样式永远不会干扰其他Lightning Web组件或Aura组件。是的,你没看错。闪电Web组件样式不会与其子级联。您不拥有的覆盖样式会造成很多问题,因此Lightning Web组件不允许这样做。

Shadow DOM的CSS封装

闪电Web组件使用一种称为阴影DOM的Web标准机制,该机制从包含该组件的页面中隐藏该组件内的元素。由于Lightning Web组件具有阴影DOM,因此在组件样式表中定义的样式将限于该组件。它们不适用于父,子或同级组件。此规则很严格,但是它允许在不同的上下文中重用组件而不会丢失其样式。它还可以防止组件的样式覆盖页面其他部分中的样式。

为了使组件作者更容易开发,Lightning Web组件的影子DOM的工作原理与Web标准有所不同。区别在于,Lightning Web组件的阴影DOM是自动创建的。组件作者不必实现它。此外,即使在本机不支持影子DOM的浏览器上,Lightning Web组件的影子DOM也可以使用。

适用于Aura开发人员的Lightning Web Components – 了解闪电Web组件如何与Aura组件一起使用

学习目标

完成本单元后,您将能够:

  • 列出Lightning Web组件的优点。
  • 描述Aura组件和Lightning Web组件如何协同工作。
  • 确定何时迁移组件。

一种新的编程模型

您现在可以在两种编程模型中开发Lightning组件:原始模型(Aura组件)和新模型(Lightning Web组件)。就在您掌握了Aura组件的开发之后,我们就提供了Lightning Web组件!为什么,哦为什么,你问?好吧,我们创建了Lightning Web Components模型来与几年前建立原始Aura模型时不存在的Web标准保持一致。

注意

您是否注意到最后一段中的大写字母不同?如果是这样,您有敏锐的眼睛。当我们引用Lightning Web Components编程模型时,所有单词都大写。仅当我们将组件本身称为Lightning Web组件时,才大写第一个单词。

同样,您一直在使用的编程模型现在称为Aura Components编程模型,您可以创建Aura组件。

为了说明这一点,您在Lightning Web Components编程模型中创建了Lightning Web组件。在“ Aura组件”编程模型中,创建Aura组件。

本模块的目的是帮助您利用Aura组件的技能来加快对Lightning Web组件的了解。您将了解两种类型的组件如何在同一个应用程序中协同工作。

什么是闪电Web组件?

Lightning Web Components是W3C的Web Components标准的实现。它支持Web组件在浏览器中运行良好的部分,并且仅添加在Salesforce支持的所有浏览器中工作所需的内容。

闪电Web组件的好处是什么?

现代JavaScript
在过去的几年中,具有ES6 +和Web标准的JavaScript语言(例如HTML模板,自定义元素和Web组件)已经有了很大的发展。Lightning Web Components为Lightning Component框架带来了现代的JavaScript和Web标准。
开发人员的生产力和满意度
学习如何更快地构建Lightning Web组件,因为您正在使用标准的JavaScript,HTML和CSS。有专有组件和API,可以更轻松地使用Salesforce,但是您可以通过标准方式访问和使用这些专有组件。
使用Lightning Web组件编写更少的代码,并且这些代码更易于阅读,维护和单元测试。
通过转到您喜欢的搜索引擎,可以更轻松地找到您的开发问题的答案。使用Web标准可以加快开发和调试时间。
使用您喜欢的开发工具,因为Lightning Web组件使用标准的JavaScript并可以与您选择的工具很好地配合使用。
代码性能
使用Web标准可以提高性能,因为更多功能是由浏览器而不是JavaScript框架本地执行的。根据使用情况的不同,这种改进可能会有所不同,但是我们相信您会为组件的更快的渲染时间感到惊喜。

先决条件

在深入学习此模块之前,请完成Lightning Web Components基础知识模块,该模块为您提供了对新编程模型的出色介绍。

我们假设您熟悉Aura Components编程模型,除了与Lightning Web Components编程模型相比,我们不会解释其功能。如果您不熟悉Aura组件,请从“ Aura组件基础知识”模块开始。

您还需要了解现代JavaScript开发和ES6 JavaScript功能。如果这些术语令人困惑,则可以在Modern JavaScript Development模块中了解它们。该模块涵盖了开发Lightning Web组件所需的所有JavaScript技能。

带扣旅行

学习任何新的编程模型或语言都是一段旅程。当您运行一些新代码时,就像在开阔的道路上驾驶敞篷车时的快感。然后,您更改一行代码,然后得到一个错误。您猛踩刹车,但遇到交通拥堵,拼命寻找下一个出口。记住,这是一个旅程。错误只是暂时的减速,您最终会到达目的地……希望在晚餐时间之前。

我们希望该模块为您的Lightning Web组件之旅做好准备。可以将模块视为打包旅行的行李箱。我们会逐步引导您完成冒险所需的一切。当您到达目的地时,我们不希望您打开行李箱并意识到您忘了打包内衣了!

组件生活在一起

让我们开始看看如何将组件组合在一起。您可以在另一个组件的主体内添加组件。这种组件组成使您可以从更简单的构建块组件中构建复杂的组件。组件组成的概念对于Aura组件和Lightning Web组件都是至关重要的。

我们知道您可能在开发Aura组件上投入了大量时间和精力。因此,我们投入了时间,使您能够在同一应用程序中组合Aura组件和Lightning Web组件。例如,您可以编写一个新的Lightning Web组件并将其添加到包含Aura组件的应用程序中。

除了将Aura组件和Lightning Web组件组合在一起之外,这两种类型的组件还可以与事件进行通信。这是一种健康的共存。

像任何关系一样,有一些规则可以确保所组成的组件一起良好地工作。

重要

允许的Aura组件 可以包含Lightning Web组件。

不允许 闪电Web组件不能包含Aura组件。

如果您要构建一个Lightning Web组件,并且其主体中还需要其他子组件,则这些子组件也必须作为Lightning Web组件构建。请记住,Lightning Web组件不能包含Aura组件。

如果Lightning Web组件是嵌套组件树中最外面的组件,则任何嵌套组件都不能是Aura组件。

两种编程模型一起工作的优点之一是,您可以决定将一个Aura组件迁移到Lightning Web组件,然后您的应用程序继续运行。即使您决定将Lightning Web组件用于新组件,您仍然可以利用对Aura组件的任何现有投资。

另外,您可以在ES6模块中编写新代码,并从Lightning Web组件和Aura组件访问该代码。这种模式为Aura开发人员打开了现代JavaScript开发的大门。

迁移策略

迁移代码很少是一条直线路。Lightning Web Components的编程模型与Aura Components的模型根本不同。将Aura组件迁移到Lightning Web组件不是逐行转换,这是重新访问组件设计的好机会。在迁移Aura组件之前,请评估该组件的属性,接口,结构,模式和数据流。

最容易迁移的组件是仅呈现UI的简单组件。性能至关重要的Aura组件很适合迁移到Lightning Web组件。

通过迁移更大的组件树(组件内的组件)而不是单个组件,可以在性能和开发人员生产率上获得更多收益。但是,迁移一个组件并查看Aura编程模型中的概念如何映射到Lightning Web Components编程模型中的概念是非常有用的学习经验。

迁移一个组件之后,您将可以更好地确定对您和您的组织是否有意义:

  • 进行更大的迁移工作。
  • 仅将Lightning Web组件用于新组件。
  • 暂时使用Aura组件。

选择权取决于您,每个人的选择都不同,具体取决于用例和可用资源。无论您做出什么决定,迁移组件都是一项有价值的学习活动。