为 Pardot 电子邮件内容生成器创建组件

电子邮件内容生成器中的自定义组件允许营销人员和经理为其客户创建更具吸引力的电子邮件内容。

为电子邮件生成器配置组件

在 Pardot 电子邮件内容生成器中提供自定义 Lightning Web 组件,用户可以将其添加到他们的电子邮件内容中。

在组件的配置文件中,添加电子邮件内容生成器的目标。设置为 。lightningStatic__Email<isExposed>true

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>53.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__AppPage</target>
    <target>lightningStatic__Email</target>
    <target>lightning__HomePage</target>
  </targets>
</LightningComponentBundle>

目标将属性添加到组件中。添加到组件的属性包括 、 、 、 和 。访问组件模板中的属性。lightningStatic__EmailBooleanColorIntegerStringHorizontalAlignmentVerticalAlignment

<template>
  <table …>
    <tr valign={valign}>
      <td>{content}</td>
    </tr>
  </table>
</template>

在组件文件中声明属性,如垂直对齐示例。js-meta.xml

// sampleCustomComponent.js-meta.xml
<targetConfigs>
  <targetConfig targets="lightningStatic__Email">
    <property name="buttonAlignment" type="VerticalAlignment" default="middle" />
    <designLayout>
      <designSection name="...">
        <designLayoutItems>
          <designLayoutProperty name="buttonAlignment" />
        </designLayoutItems>
      </designSection>
    </designLayout>
  </targetConfig>
</targetConfigs>

在项目目录中使用以下命令为自定义组件准备元数据包。创建的文件夹名称为 。custompackage

sf project convert source -d custompackage

将包部署到测试组织。首先,通过登录到要部署包的任意组织来创建别名。使用以下命令登录并命名别名。

sf org login web -r http://login.salesforce.com -a isvorg

使用以下命令将包部署到您授权的别名。

sf project deploy --metadata-dir -d custompackage -u isvorg

您可以通过登录到部署的目标组织来验证部署是否已完成。在“设置”的“快速查找”框中,输入 ,然后选择“部署状态”。Deployment Status

自定义组件已部署。在“设置”的“快速查找”框中,输入 ,然后选择 Lightning 组件Lightning Components

测试目标组织中的组件,以验证自定义组件是否可以在电子邮件内容生成器中使用。

自定义组件的注意事项

在 Lightning 应用程序生成器中工作的某些自定义组件与电子邮件内容生成器不兼容。在启用现有自定义组件以在电子邮件构建器中使用它们之前,请查看这些组件的要求。

不支持的项目

为我们的内容构建器提供支持的渲染引擎在安全的环境中运行。但是,在自定义组件文件中可以添加的代码存在限制。

  • 任何类型的 DOM API
  • 文件中的生命周期挂钩renderedCallback().js
  • 文件中的 Web API 方法fetch().js
  • <script>标记.html
  • 对文件中对象的引用window.js
  • 命名空间中的基本组件lightning
  • 使用语法的线路服务@wire
  • Apex 方法,但PicklistEntry

CSS 文件

  • 不支持 SLDS 令牌和选择器。:host
  • 我们建议您使用唯一的类名或在 CSS 类名前面加上命名空间,以区别于其他组件。

选择列表

  • 通过使用 Apex 创建 HTML 标记来填充选择列表。请参阅 Apex 参考指南 PicklistEntry 类。
  • 仅当覆盖以下方法时,用作选择列表数据源的 Apex 外部标注才有效:global override Boolean isValid(Object attributeValue){return true;}

向组件添加自定义 HTML

您可以将自定义 HTML 添加到组件中,以便在电子邮件内容构建器中使用。

在模板标记中指定要位于 innerHTML 容器中的元素的特殊属性和值:.ishtmlcontainer="true"

不要在其他地方使用,因为它不会处理生成 HTML 的时间。renderedCallback()

在模板中,将属性和值附加到要指定 innerHTML 容器的位置。ishtmlcontainer="true"

<template>
  <div ishtmlcontainer="true" lwc:dom="manual"></div>
</template>

在 JavaScript 文件中,为属性创建 setter 和 getter。暂时将它们留空。htmlValue

@api
set htmlValue(value) {

}

get htmlValue() {

}

添加一个方法,在该方法中创建一个实例变量,以保存对保存 innerHTML 属性的元素的引用(称为 )。在该元素的 innerHTML 属性上,为其分配刚创建的属性的值。renderedCallback()attachmentPoint

renderedCallback() {
    this.attachmentPoint = this.template.querySelector('div[ishtmlcontainer=true]');
    this.attachmentPoint.innerHTML = this.htmlValue;
}

在 setter 中,添加对所创建的实例变量的赋值的检查。将新值分配给实例变量的 innerHTML 属性,并将该值分配给非公共属性。在 getter 中,返回非公共属性的值。

import { LightningElement, api } from "lwc";

export default class CustomInner extends LightningElement {
  @api
  set htmlValue(value) {
    if (this.attachmentPoint) {
      this.attachmentPoint.innerHTML = value;
    }
    this._htmlValue = value;
  }

  get htmlValue() {
    return this._htmlValue;
  }

  renderedCallback() {
    this.attachmentPoint = this.template.querySelector("div[ishtmlcontainer=true]");
    this.attachmentPoint.innerHTML = this.htmlValue;
  }
}

在文件中定义属性的默认值和其他属性。.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="CustomInner">
    <apiVersion>53.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Custom Inner HTML</masterLabel>
    <description>Display HTML-enhanced text</description>
    <targets>
        <target>lightningStatic__Email</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightningStatic__Email">
            <property name="htmlValue" type="String" required="true" default="YOUR CUSTOM INNER HTML HERE"/>
            ...
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

为 CRM Analytics 仪表板配置组件

使用 Lightning Web 组件实现自定义功能,然后将它们与 CRM Analytics 仪表板小组件和步骤交互使用。

1. 在配置文件中添加 CRM Analytics 目标

componentName.js-meta.xml 文件定义组件的元数据值,包括允许在 CRM Analytics 仪表板中使用的设置。将目标添加到组件的配置文件中。确保将属性设置为 ,以便组件对 CRM Analytics 设计器 UI 可见。analytics__DashboardisExposedtrue

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <isExposed>true</isExposed>
    <targets>
        <target>analytics__Dashboard</target>
    </targets>
</LightningComponentBundle>

2. 设置组件配置选项

在 componentName.js-meta.xml 文件中,为目标添加 a。如果组件设计为使用仪表板步骤中的 CRM Analytics 查询数据,则将标记设置为。对于设计用于 CRM Analytics 仪表板的每个组件属性,添加标记。targetConfiganalytics__DashboardhasSteptrueproperty

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <targetConfig targets="analytics__Dashboard">
        <hasStep>true</hasStep>
        <property name="title" type="String" label="Title" description="Component Title" required="true" />
    </targetConfig>
</LightningComponentBundle>

除了常见的数据类型外,目标还支持具有 的组件的数据类型。仪表板编辑器能够从附加步骤的结果中选择给定数据类型的列。analytics__DashboardMeasureDimension<hasStep>true</hasStep>

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <targetConfig targets="analytics__Dashboard">
        <hasStep>true</hasStep>
        <property name="labelColumn" type="Dimension" label="Label Column" description="Segment Label" required="true" />
    </targetConfig>
</LightningComponentBundle>

完成这些步骤后,在 CRM Analytics Studio 仪表板编辑器中将 Lightning Web 组件添加为组件小部件。有关详细信息,请参阅《CRM Analytics 仪表板中的 Lightning Web 组件开发人员指南》。

使用 Lightning Message Service 跨 DOM 进行通信

使用 Lightning 消息服务在 Lightning 页面内的 DOM 之间进行通信。在同一 Lightning 页面中嵌入的 Visualforce 页面、Aura 组件和 Lightning Web 组件(包括实用程序栏中的组件和弹出式实用程序)之间进行通信。选择组件是订阅来自整个应用程序的消息,还是仅订阅来自活动区域的消息。

如果您要从 Salesforce Classic 切换到 Lightning Experience,则可以构建与现有 Visualforce 页面或 Aura 组件进行通信的 Lightning Web 组件。您还可以使用 Lightning 消息服务通过 Open CTI 与软件电话进行通信。

重要

Lightning 消息服务在 Lightning Experience 和 Experience Builder 站点中使用的 Lightning 组件中可用。

创建消息通道

要创建 Lightning 消息通道,请使用 LightningMessageChannel 元数据类型。

在组织中定义消息通道元数据

要将 LightningMessageChannel 部署到您的组织中,请创建一个 SFDX 项目。在目录中包括 XML 定义。LightningMessageChannel 文件名遵循以下格式。force-app/main/default/messageChannels/messageChannelName.messageChannel-meta.xml

有关元数据文件的示例,请参阅元数据 API 开发人员指南:LightningMessageChannel。

要将其添加到临时组织,请运行 。sf project deploy start

要将其添加到其他类型的组织(如沙盒或 Developer Edition 组织),请运行 。sf project deploy start

导入消息通道

以下是导入 Lightning 消息通道的方法,组件可以使用该通道通过 Lightning 消息服务进行通信。

// Syntax
import channelName from "@salesforce/messageChannel/channelReference";
// Syntax for resources in a managed package
import channelName from "@salesforce/messageChannel/namespace__channelReference";
// Example
import recordSelected from "@salesforce/messageChannel/Record_Selected__c";
  • channelName– 用于标识消息通道的导入符号。
  • channelReference– 消息通道的 API 名称。
  • namespace– 如果消息通道位于受管软件包中,则此值为受管软件包的名称空间。如果消息通道不在托管包中,请不要包含命名空间。

注意

Record_Selected__c指 LightningMessageChannel 元数据类型的自定义实例。尽管它使用后缀,但它不是自定义对象。__c

定义邮件服务的作用域

Lightning 消息服务允许您定义订阅组件在应用程序中接收消息的范围。您可以将范围限制为应用程序的活动区域,也可以将范围设置为整个应用程序。

重要

对于 Lightning Web 组件,范围功能仅在使用 时可用。@wire(MessageContext)

应用程序的活动区域包括选定的导航选项卡和项目、实用程序项目和 ES6 库。实用程序项目始终处于活动状态。导航选项卡和项目包括:

  • 标准导航选项卡
  • 控制台导航工作区选项卡
  • 控制台导航子选项卡
  • 控制台导航项

要从应用程序中的任何位置接收消息通道上的消息,请从 导入。然后,调用并传递可选的第四个参数。APPLICATION_SCOPElightning/messageServicesubscribe(){ scope: APPLICATION_SCOPE }subscriberOptions

// Import message service features.
import {
    subscribe,
    unsubscribe,
    APPLICATION_SCOPE,
    MessageContext
} from 'lightning/messageService';

// To pass scope, you must get a message context.
@wire(MessageContext)
    messageContext;

// Pass scope to the subscribe() method.
    subscribeToMessageChannel() {
        if (!this.subscription) {
            this.subscription = subscribe(
                this.messageContext,
                recordSelected,
                (message) => this.handleMessage(message),
                { scope: APPLICATION_SCOPE }
            );
        }
    }

从活动区域接收消息是默认行为。无需包含 scope 属性即可将范围限制为活动区域。

在消息通道上发布

要从 Lightning Web 组件在消息通道上发布消息,请在组件的 JavaScript 文件中包含作用域模块,并调用 Lightning 消息服务的函数。@salesforce/messageChannelpublish()

Lightning 消息服务将消息发布到任何订阅的组件,直到组件生命周期的销毁阶段。有时,当您离开 Lightning 页面时,组件会被缓存而不是销毁。如果 Lightning 消息服务的范围限定为整个应用程序,则这些组件仍会向 Lightning 消息服务发布消息并从 Lightning 消息服务接收消息。

提示

lwc-recipes 存储库有一个组件,用于在 Lightning 页面上发布消息以通知订阅者。Lightning 消息服务在页面上的 Visualforce、Aura 和 Lightning Web 组件之间传达该消息。lmsPublisherWebComponent

让我们看一下 lmsPublisherWebComponent 组件。组件的 HTML 模板文件显示联系人列表。选择联系人后,将调用处理程序,该处理程序将消息发布到消息通道。handleContactSelect

<!-- lmsPublisherWebComponent.html -->
<template>
  <lightning-card title="LMSPublisherWebComponent" icon-name="custom:custom30">
    <div class="slds-m-around_medium" oncontactselect={handleContactSelect}>
      <template lwc:if={contacts.data}>
        <template for:each={contacts.data} for:item="contact">
          <c-contact-list-item-bubbling
            key={contact.Id}
            contact={contact}>
          </c-contact-list-item-bubbling>
        </template>
      </template>
    </div>
  </lightning-card>
</template>

在组件的 JavaScript 文件中,导入使用消息通道所需的消息通道和 Lightning 消息服务函数。

// lmsPublisherWebComponent.js
import { LightningElement, wire } from "lwc";
import getContactList from "@salesforce/apex/ContactController.getContactList";

// Import message service features required for publishing and the message channel
import { publish, MessageContext } from "lightning/messageService";
import recordSelected from "@salesforce/messageChannel/Record_Selected__c";

export default class LmsPublisherWebComponent extends LightningElement {
  @wire(getContactList)
  contacts;

  @wire(MessageContext)
  messageContext;

  // Respond to UI event by publishing message
  handleContactSelect(event) {
    const payload = { recordId: event.target.contact.Id };

    publish(this.messageContext, recordSelected, payload);
  }
}

用于创建一个对象,该对象提供有关使用 Lightning 消息服务的 Lightning Web 组件的信息。使用适配器时,您不必与组件的任何生命周期事件进行交互。当组件被销毁时,Lightning 消息服务功能会自动注销。@wire(MessageContext)MessageContext@wire(MessageContext)

该方法创建要发布的消息内容。闪电消息服务的函数采用三个参数:消息上下文、消息通道名称和消息有效负载。在这里,消息有效负载是一个 JSON 对象,其中键的值为 。handleContactSelect()publish()recordIdevent.target.contact.Id

注意

组件必须附加到 DOM,然后才能使用用 修饰的属性。不能在函数中使用。@wire(MessageContext)@wire(MessageContext)constructor()

订阅和取消订阅消息通道

要订阅和取消订阅消息通道上的消息,请将消息通道从作用域模块导入到 Lightning Web 组件中。调用 Lightning 消息服务和函数。@salesforce/messageChannelsubscribe()unsubscribe()

提示

lwc-recipes 存储库有一个组件,用于显示如何订阅和取消订阅消息通道。此示例适用于“在消息通道上发布”中的发布者组件。lmsSubscriberWebComponent

让我们看一下 lmsSubscriberWebComponent 组件。从发布者组件中选择联系人会将所选记录 ID 发布到消息通道。Record_Selected__c

订阅者组件的 HTML 对已发布的消息做出反应,并显示其记录 ID 通过消息负载提供的联系人的数据。

<!-- lmsSubscriberWebComponent.html -->
<template>
  <lightning-card title="LMSSubscriberWebComponent" icon-name="custom:custom30">
    <div class="slds-m-around_medium">
      <template lwc:if={Picture__c}>
        <img src={Picture__c} alt="Profile photo" />
      </template>
      <p>{Name}</p>
      <p>{Title}</p>
      <p>
        <lightning-formatted-phone value={Phone}></lightning-formatted-phone>
      </p>
      <p>
        <lightning-formatted-email value={Email}></lightning-formatted-email>
      </p>
    </div>
  </lightning-card>
</template>

在组件的 JavaScript 中,导入从 订阅所需的消息服务功能。从 导入消息通道。lightning/messageServiceRecord_Selected__c@salesforce/messageChannel

用于创建 Context 对象,该对象提供有关使用 Lightning 消息服务的 Lightning Web 组件的信息。组件必须附加到 DOM,然后才能使用用 修饰的属性。@wire(MessageContext)@wire(MessageContext)

该函数检查是否为 null。如果订阅为 null,则调用 Lightning 消息服务的方法并将其分配给 。该方法采用三个必需的参数:消息上下文、消息通道的名称以及处理已发布消息的侦听器方法。调用侦听器方法时,它会将消息传递给 。 从它收到的 JSON 消息有效负载中提取属性。然后,使用与记录 ID 匹配的联系人相关的信息更新 HTML 模板。subscribeToMessageChannel()subscriptionsubscribe()subscriptionsubscribe()handleMessage()handleMessage()recordId

若要从应用程序中的任何位置接收消息通道上的消息,请将该方法的第四个参数作为可选参数传递。请参阅定义邮件服务的作用域。{ scope: APPLICATION_SCOPE }subscribe()

要停止接收来自 Lightning 消息服务的消息,请调用 ,传入订阅引用。该对象包含对要取消订阅的订阅的引用。此示例调用 ,后者调用 ,然后设置为 null。unsubscribe()subscriptionunsubscribeToMessageChannel()unsubscribe()subscription

// lmsSubscriberWebComponent.js
import { LightningElement, wire } from "lwc";
import { getRecord, getFieldValue } from "lightning/uiRecordApi";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import { reduceErrors } from "c/ldsUtils";

// Import message service features required for subscribing and the message channel
import {
  subscribe,
  unsubscribe,
  APPLICATION_SCOPE,
  MessageContext,
} from "lightning/messageService";
import recordSelected from "@salesforce/messageChannel/Record_Selected__c";

import NAME_FIELD from "@salesforce/schema/Contact.Name";
import TITLE_FIELD from "@salesforce/schema/Contact.Title";
import PHONE_FIELD from "@salesforce/schema/Contact.Phone";
import EMAIL_FIELD from "@salesforce/schema/Contact.Email";
import PICTURE_FIELD from "@salesforce/schema/Contact.Picture__c";

const fields = [NAME_FIELD, TITLE_FIELD, PHONE_FIELD, EMAIL_FIELD, PICTURE_FIELD];

export default class LmsSubscriberWebComponent extends LightningElement {
  subscription = null;
  recordId;

  Name;
  Title;
  Phone;
  Email;
  Picture__c;

  @wire(getRecord, { recordId: "$recordId", fields })
  wiredRecord({ error, data }) {
    if (error) {
      this.dispatchToast(error);
    } else if (data) {
      fields.forEach((item) => (this[item.fieldApiName] = getFieldValue(data, item)));
    }
  }

  @wire(MessageContext)
  messageContext;

  // Encapsulate logic for Lightning message service subscribe and unsubsubscribe
  subscribeToMessageChannel() {
    if (!this.subscription) {
      this.subscription = subscribe(
        this.messageContext,
        recordSelected,
        (message) => this.handleMessage(message),
        { scope: APPLICATION_SCOPE },
      );
    }
  }

  unsubscribeToMessageChannel() {
    unsubscribe(this.subscription);
    this.subscription = null;
  }

  // Handler for message received by component
  handleMessage(message) {
    this.recordId = message.recordId;
  }

  // Standard lifecycle hooks used to subscribe and unsubsubscribe to the message channel
  connectedCallback() {
    this.subscribeToMessageChannel();
  }

  disconnectedCallback() {
    this.unsubscribeToMessageChannel();
  }

  // Helper
  dispatchToast(error) {
    this.dispatchEvent(
      new ShowToastEvent({
        title: "Error loading contact",
        message: reduceErrors(error).join(", "),
        variant: "error",
      }),
    );
  }
}

注意

如果创建的服务组件不是 ,则不能用于创建对象。而是从 import 和 methods。用于创建 Context 对象并将其分配给字段,如 .然后,传入方法。不会自动为服务组件发布上下文。调用以删除与组件的消息上下文关联的任何订阅。LightningElement@wire(MessageContext)MessageContextcreateMessageContext()releaseMessageContext()lightning/messageServicecreateMessageContext()messageContextmessageContextsubscribe()releaseMessageContext(messageContext)

Lightning 消息服务限制

使用 Lightning 消息服务时,请记住以下几点。

Lightning 消息服务仅支持以下体验:

  • Lightning Experience 标准导航
  • Lightning Experience 控制台导航
  • 适用于 Aura 和 Lightning Web 组件的 Salesforce 移动应用程序,但不适用于 Visualforce 页面
  • Aura 和基于 LWR 的 Experience Builder 站点中使用的 Lightning 组件。注意Lightning 消息服务不适用于 Salesforce 选项卡 + Visualforce 站点或 Experience Builder 站点中的 Visualforce 页面。

在不支持 Lightning 消息传递服务的容器中,使用该模块。从 github.com/developerforce/pubsub 下载模块。pubsub

在 AppExchange 上发布的包中包含消息通道时,支持 1GP 和 2GP 包。

对于 Lightning Web 组件,您可以定义订阅组件仅在使用 时在应用程序中接收消息的范围。@wire(MessageContext)

使用移动设备功能

移动功能允许您在 Lightning Web 组件中使用移动设备功能。直接从您的组件代码访问摄像头和位置检测硬件,以及联系人和日历数据等平台功能。使用这些特定于移动设备的功能构建感觉像本机移动应用程序的 Lightning 应用程序。

《移动和离线开发人员指南》中提供了完整的详细信息,该指南是执行移动开发时本指南的重要配套。

显示通知

组件可以发送弹出的通知以提醒用户、请求用户确认、提示响应或仅提供信息。

警报模态

使用警报模式来停止用户,并传达影响其系统、功能或页面的紧急错误。要在 Lightning Experience 中显示警报模式,请从模块导入,然后使用所需的属性进行调用。LightningAlertlightning/alertLightningAlert.open()

注意

此警报模式是原生函数的替代方法,Chrome 和 Safari 中的跨域 iframe 不支持该函数。与本机警报函数不同,它不会停止页面上的执行,而是返回 Promise。使用 / 或 用于要在模式关闭后执行的任何代码。window.alert()LightningAlert.open()asyncawait.then()

此示例组件创建一个按钮,用于打开在屏幕截图中看到的警报模式 UI。通常,错误条件会触发警报模式的显示。

<!-- c/myApp.html -->
<template>
  <lightning-button onclick={handleAlertClick} label="Open Alert Modal"> </lightning-button>
</template>

在打开警报模式的组件的 JavaScript 文件中导入。创建并调度具有 、 和 属性的事件。该函数返回一个 promise,当您单击“确定”时,该 promise 将解析。LightningAlertlightning/alertLightningAlertmessagethemelabel.open()

// c/myApp.js
import { LightningElement } from "lwc";
import LightningAlert from "lightning/alert";

export default class MyApp extends LightningElement {
  async handleAlertClick() {
    await LightningAlert.open({
      message: "This is the alert message.",
      theme: "error", // a red theme intended for error states
      label: "Error!", // this is the header text
    });
    // alert modal has been closed
  }
}

有关警报模式属性的信息,请参阅组件参考。

确认模态

使用确认模式要求用户在继续操作之前做出响应。要在 Lightning Experience 中显示确认模式,请从模块导入,然后使用所需的属性进行调用。LightningConfirmlightning/confirmLightningConfirm.open()

注意

此确认模式是原生函数的替代方法,Chrome 和 Safari 中的跨域 iframe 不支持该函数。与本机 confirm 函数不同,它不会停止页面上的执行,而是返回一个 Promise。使用 / 或 用于要在模式关闭后执行的任何代码。window.confirm()LightningConfirm.open()asyncawait.then()

此示例组件创建一个按钮,用于打开您在屏幕截图中看到的确认模式 UI。

<!-- c/myApp.html -->
<template>
  <lightning-button onclick={handleConfirmClick} label="Open Confirm Modal"> </lightning-button>
</template>

在打开确认模式的组件的 JavaScript 文件中导入。创建并调度具有 、 和 属性的事件。该函数返回一个 promise,该 promise 解析为单击“确定”和单击“取消”时。LightningConfirmlightning/confirmLightningConfirmmessagevariantlabel.open()truefalse

// c/myApp.js
import { LightningElement } from "lwc";
import LightningConfirm from "lightning/confirm";

export default class MyApp extends LightningElement {
  async handleConfirmClick() {
    const result = await LightningConfirm.open({
      message: "This is the confirmation message.",
      variant: "headerless",
      label: "This is the aria-label value",
      // label value isn't visible in the headerless variant
    });
    // confirm modal has been closed
  }
}

有关确认模式的属性的信息,请参阅组件参考。

提示模态

使用提示模式要求用户在继续操作之前提供信息。要在 Lightning Experience 中显示提示模式,请从模块导入,然后使用所需的属性进行调用。LightningPromptlightning/promptLightningPrompt.open()

注意

此提示模式是原生函数的替代方法,Chrome 和 Safari 中的跨域 iframe 不支持该函数。与本机提示函数不同,它不会停止页面上的执行,而是返回 Promise。使用 / 或 用于要在模式关闭后执行的任何代码。window.prompt()LightningPrompt.open()asyncawait.then()

此示例组件创建一个按钮,用于打开在屏幕截图中看到的提示模式 UI。

<!-- c/myApp.html -->
<template>
  <lightning-button onclick={handlePromptClick} label="Open Prompt Modal"> </lightning-button>
</template>

在打开提示模式的组件的 JavaScript 文件中导入。创建并调度具有 、 、 和 属性的事件。如果用户输入文本并在提示中单击“确定”,则该函数将返回解析为输入值的 promise。如果用户单击“取消”,该函数将返回解析为 的 promise。LightningPromptlightning/promptLightningPromptmessagethemelabeldefaultValue.open()null

import { LightningElement } from "lwc";
import LightningPrompt from "lightning/prompt";

export default class MyApp extends LightningElement {
  handlePromptClick() {
    LightningPrompt.open({
      message: "This is the prompt message.",
      //theme defaults to "default"
      label: "Please Respond!", // this is the header text
      defaultValue: "Optional initial input value",
    }).then((result) => {
      // prompt modal has been closed
    });
  }
}

有关提示模式属性的信息,请参阅组件参考。

Toast 通知

组件可以发送弹出的 Toast 通知,以提醒用户成功、错误或警告。祝酒词也可以简单地提供信息。

要在 Experience Cloud 的 Lightning Experience 或 Aura 站点中显示 Toast 通知,请从模块导入。ShowToastEventlightning/platformShowToastEvent

注意

ShowToastEvent在 Aura 站点的登录页面上不受支持。 在 Experience Cloud 的 LWR 站点中也不受支持。请改用 lightning/toastContainer 模块 (Beta)。ShowToastEvent

lwc-recipes 存储库有一个组件,可用于自定义和发送 Toast,以便您可以尝试变体。

HTML 模板生成在屏幕截图中看到的 UI。

<!-- miscToastNotification.html -->
<template>
  <lightning-card title="miscToastNotification" icon-name="custom:custom19">
    <div class="slds-m-around_medium">
      <lightning-input label="Title" value={_title} onchange={titleChange}></lightning-input>
      <lightning-input
        label="Message"
        value={message}
        onchange={messageChange}>
      </lightning-input>
      <lightning-combobox
        label="Variant"
        value={variant}
        onchange={variantChange}
        options={variantOptions}>
      </lightning-combobox>
      <p class="slds-m-vertical_small">
        <lightning-button label="Show Notification" onclick={showNotification}></lightning-button>
      </p>
    </div>
  </lightning-card>
</template>

只需从 .创建和调度具有 、 、 和 属性的事件。此示例使用 的默认值 ,因此不包括在内。ShowToastEventlightning/platformShowToastEventShowToastEventtitlemessagevariantmodemode

// miscToastNotification.js
import { LightningElement } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";

export default class MiscToastNotification extends LightningElement {
  _title = "Sample Title";
  message = "Sample Message";
  variant = "error";
  variantOptions = [
    { label: "error", value: "error" },
    { label: "warning", value: "warning" },
    { label: "success", value: "success" },
    { label: "info", value: "info" },
  ];

  titleChange(event) {
    this._title = event.target.value;
  }

  messageChange(event) {
    this.message = event.target.value;
  }

  variantChange(event) {
    this.variant = event.target.value;
  }

  showNotification() {
    const evt = new ShowToastEvent({
      title: this._title,
      message: this.message,
      variant: this.variant,
    });
    this.dispatchEvent(evt);
  }
}
ShowToastEvent参数类型描述
title字符串Toast 的标题,显示为标题。
message字符串一个字符串,包含用户的消息。
messageDataString[] 或 Objecturl以及替换字符串中占位符的值。label{index}message
variant字符串Toast 中显示的主题和图标。有效值为:info—(默认)带有信息图标的灰色框。success– 带有复选标记图标的绿色框。warning– 带有警告图标的黄色框。error– 带有错误图标的红色框。您可以在 Lightning Design System 文档中查看每个主题的样式。
mode字符串确定 Toast 的持久性。有效值为:dismissible—(默认)保持可见,直到用户单击关闭按钮或 3 秒过去,以先到者为准。pester– 保持可见 3 秒。sticky– 在用户单击关闭按钮之前保持可见。

提示

要运行此代码,请将 github.com/trailheadapps/lwc-recipes 源推送到 Salesforce 组织。

导航到页面、记录和列表

要在 Lightning Experience、Experience Builder 站点和 Salesforce 移动应用程序中导航,请使用导航服务 .lightning/navigation

该服务仅在 Lightning Experience、Experience Builder 站点和 Salesforce 移动应用程序中受支持。其他容器不支持它,例如 Lightning Components for Visualforce 或 Lightning Out。即使您在 Lightning Experience 或 Salesforce 移动应用程序中访问这些容器,也是如此。lightning/navigation

基本导航

使用导航服务 导航到许多不同的页面类型,如记录、列表视图和对象。还可以使用导航服务打开文件。lightning/navigation

导航服务使用 .PageReference 是一个 JavaScript 对象,用于描述页面类型、其属性和页面状态。使用 a 可以使组件免受将来对 URL 格式的更改的影响。它还允许您的组件在多个应用程序中使用,每个应用程序都可以使用不同的 URL 格式。PageReferencePageReference

PageReference财产类型描述必填
type字符串要在 Lightning Experience、Experience Builder 站点或 Salesforce 移动应用程序中导航,请定义一个对象。该类型生成唯一的 URL 格式,并定义应用于该类型的所有页面的属性。对于 Experience Builder 站点,根据页面类型,LWR 站点和 Aura 站点之间的属性要求可能有所不同。请参见 PageReference 类型。PageReferencePageReferencePageReference是的
attributes对象确定目标页面的名称/值对的映射。页面类型定义可能的属性名称集及其各自的值类型。是的
state对象一组具有字符串键和字符串值的键值对。这些参数有条件地自定义给定页面中的内容。某些页面引用类型支持一组标准属性。还可以将非标准属性传递到只要它们具有命名空间即可。statestate

导航服务将两个 API 添加到组件的类中。由于这些 API 是类上的方法,因此请从 调用它们。this

  • [NavigationMixin.Navigate](pageReference, [replace])组件调用以导航到应用程序中的另一个页面。this[NavigationMixin.Navigate]
  • [NavigationMixin.GenerateUrl](pageReference)组件调用以获取解析为生成的 URL 的 URL。该组件可以在定位点的属性中使用 URL。它还可以使用 URL 通过浏览器 API 打开新窗口。this[NavigationMixin.GenerateUrl]promisehrefwindow.open({url})

使用导航服务

  1. 在组件的 JavaScript 类中,从 lightning/navigation 模块导入函数。NavigationMixinimport { NavigationMixin } from "lightning/navigation";
  2. 将该函数应用于组件的基类。NavigationMixinexport default class MyCustomElement extends NavigationMixin(LightningElement) {}
  3. 创建一个用于定义页面的纯 JavaScript PageReference 对象。
  4. 若要调度导航请求,请调用导航服务的函数。如果设置为 ,则替换浏览器历史记录中的现有条目,以便用户不必按两次后退按钮。缺省值为 。[NavigationMixin.Navigate]({pageReference}, [{replace}]){replace}true{pageReference}falsenavigateNext() { this[NavigationMixin.Navigate]({ type: 'standard__navItemPage', attributes: { apiName: this.tabName, }, }); }

当您使用 导航到页面引用时,例如从启用了快速操作的组件,默认情况下不会自动关闭该模式。例如,如果组件导航到记录创建页面,则包含组件的模式将保持打开状态,但处于非活动状态,而另一个模式则将其与记录创建页面覆盖。当您使用记录创建页面关闭新模式时,包含组件的先前模式将再次变为活动状态。要在导航时自动关闭上一个模式,请设置为 。[NavigationMixin.Navigate](pageReference, [replace])replacetrue

示例:导航到帐户主页

此示例显示指向帐户主页的链接。当用户单击该链接时,事件处理程序 将调用导航服务的方法,该方法将加载帐户主页。帐户主页 URL 也可在锚标记中找到,该标记允许用户复制链接或在新窗口中打开它。clickhandleClickNavigate

<!-- navigationLinkExample.html -->
<template>
  <div>
    <a href={url} onclick={handleClick}>Account Home</a>
  </div>
</template>

在组件的 JavaScript 文件中,导入导航服务。

若要导航到帐户主页并生成其 URL,导航服务使用一个对象。当组件插入到 DOM 中时,对象 在生命周期钩子中定义。导航服务将帐户主页 URL 存储在模板中使用的属性中。PageReferencePageReferenceaccountHomePageRefconnectedCallback()url

事件处理程序也在组件的 JavaScript 类中定义,并导航到页面引用 .handleClickaccountHomePageRef

// navigationLinkExample.js
import { LightningElement, wire } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class NavigationLinkExample extends NavigationMixin(LightningElement) {
  url;

  connectedCallback() {
    // Store the PageReference in a variable to use in handleClick.
    // This is a plain Javascript object that conforms to the
    // PageReference type by including 'type' and 'attributes' properties.
    // The 'state' property is optional.
    this.accountHomePageRef = {
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Account",
        actionName: "home",
      },
    };
    this[NavigationMixin.GenerateUrl](this.accountHomePageRef).then((url) => (this.url = url));
  }

  handleClick(evt) {
    // Stop the event's default behavior.
    // Stop the event from bubbling up in the DOM.
    evt.preventDefault();
    evt.stopPropagation();
    // Navigate to the Account Home page.
    this[NavigationMixin.Navigate](this.accountHomePageRef);
  }
}

添加查询参数

若要向 URL 添加查询参数,请更新该属性。导航服务使用 a 来生成 URL。属性的键值对将序列化为 URL 查询参数。查询参数描述页面并形成用户可以保存或添加书签的更具体的 URL。PageReference.statePageReferencestate

使用 state 属性

使用属性时,请牢记这些行为。state

  • 对象已冻结,因此无法直接更改它。要导航到具有修改后的同一页面,请复制当前页面并使用 修改副本。PageReferencestatePageReferenceObject.assign({}, pageReference)
  • state属性必须使用命名空间前缀,后跟两个下划线。如果组件不是托管包的一部分,请使用命名空间前缀。如果组件是托管包的一部分,请使用包的命名空间。__c
  • 由于 的键值对序列化为 URL 查询参数,因此所有值都必须是字符串。PageReference.state
  • 使用值的代码必须将值分析为其正确的格式。state
  • 要从对象中删除值,请将其设置为 。stateundefined
  • 即使使用 HTTPS,在 URL 参数中包含个人数据也不安全。有关详细信息,请参阅存储敏感数据。
  • 在使用 Aura 或 LWR 模板构建的 Lightning Experience 和 Experience Builder 站点中,仅当 URL 查询字符串发生更改时,不会重新呈现视图。为了对 URL 查询字符串中的更改做出反应,我们建议组件观察该对象并与页面引用的 .CurrentPageReferencestate

示例:更新当前页面状态

此示例中的组件有一个标记为“显示面板”的链接,单击该链接时将更改为“隐藏面板”。单击任一链接都会更新当前页面的状态。当页面状态更改时,用 修饰的属性将更新。组件将重新呈现以显示或隐藏面板并更新链接标签。this.currentPageReference@wire(CurrentPageReference)

<!-- pageStateChangeExample.html -->
<template>
  <div>
    <a href={showPanelUrl} onclick={handleShowPanelClick}>Show Panel</a>
  </div>
  <div lwc:if={showPanel}>
    <h1>This is the panel</h1>
    <a href={noPanelUrl} onclick={handleNoPanelClick}>Hide Panel</a>
  </div>
</template>
// pageStateChangeExample.js
import { LightningElement, wire } from "lwc";
import { CurrentPageReference, NavigationMixin } from "lightning/navigation";

export default class PageStateChangeExample extends NavigationMixin(LightningElement) {
  // Declare the currentPageReference variable in order to track it
  currentPageReference;
  // Injects the page reference that describes the current page
  @wire(CurrentPageReference)
  setCurrentPageReference(currentPageReference) {
    this.currentPageReference = currentPageReference;

    if (this.connected) {
      // We need to have the currentPageReference, and to be connected before
      // we can use NavigationMixin
      this.generateUrls();
    } else {
      // NavigationMixin doesn't work before connectedCallback, so if we have
      // the currentPageReference, but haven't connected yet, queue it up
      this.generateUrlOnConnected = true;
    }
  }

  showPanelUrl;
  noPanelUrl;

  // Determines the display for the component's panel
  get showPanel() {
    // Derive this property's value from the current page state
    return this.currentPageReference && this.currentPageReference.state.c__showPanel == "true";
  }

  generateUrls() {
    this[NavigationMixin.GenerateUrl](this.showPanelPageReference).then(
      (url) => (this.showPanelUrl = url),
    );
    this[NavigationMixin.GenerateUrl](this.noPanelPageReference).then(
      (url) => (this.noPanelUrl = url),
    );
  }

  // Returns a page reference that matches the current page
  // but sets the 'c__showPanel' page state property to 'true'
  get showPanelPageReference() {
    return this.getUpdatedPageReference({
      c__showPanel: "true", // Value must be a string
    });
  }

  // Returns a page reference that matches the current page
  // but removes the 'c__showPanel' page state property
  get noPanelPageReference() {
    return this.getUpdatedPageReference({
      // Removes this property from the state
      c__showPanel: undefined,
    });
  }

  // Utility function that returns a copy of the current page reference
  // after applying the stateChanges to the state on the new copy
  getUpdatedPageReference(stateChanges) {
    // The currentPageReference property is read-only.
    // To navigate to the same page with a modified state,
    // copy the currentPageReference and modify the copy.
    return Object.assign({}, this.currentPageReference, {
      // Copy the existing page state to preserve other parameters
      // If any property on stateChanges is present but has an undefined
      // value, that property in the page state is removed.
      state: Object.assign({}, this.currentPageReference.state, stateChanges),
    });
  }

  connectedCallback() {
    this.connected = true;

    // If the CurrentPageReference returned before this component was connected,
    // we can use NavigationMixin to generate the URLs
    if (this.generateUrlOnConnected) {
      this.generateUrls();
    }
  }

  handleShowPanelClick(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    // This example passes true to the 'replace' argument on the navigate API
    // to change the page state without pushing a new history entry onto the
    // browser history stack. This prevents the user from having to press back
    // twice to return to the previous page.
    this[NavigationMixin.Navigate](this.showPanelPageReference, true);
  }

  handleNoPanelClick(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    this[NavigationMixin.Navigate](this.noPanelPageReference, true);
  }
}

导航服务支持 Lightning 中不同类型的页面。每种类型都支持一组不同的特性和状态属性。这两个 API 都支持这些类型。PageReferencePageReference

示例:导航到页面

让我们看一个示例,说明如何创建导航到页面的按钮。

我们的示例有一个组件,它是 Salesforce 应用程序中的一个页面。在页面底部,有一个带有标签 Next 的组件。可以在每个页面的底部使用该组件,让用户浏览应用程序。welcomenavtabnavtab

<!-- welcome.html -->
<!-- lots and lots of code removed for brevity -->

<div class="slds-m-vertical_large">
  <c-navtab tab-name="lightning_components" label="Next"></c-navtab>
</div>

该组件自定义组件以导航到应用程序中的下一页。使用者指定 a 和 a 。c-nav-tablightning-buttontab-namelabel

<!-- navTab.html -->
<template>
  <lightning-button variant="brand" label={label} title={label} onclick={navigateNext}>
  </lightning-button>
</template>
// navTab.js
import { LightningElement, api } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class Navtab extends NavigationMixin(LightningElement) {
  @api tabName;
  @api label;
  navigateNext() {
    this[NavigationMixin.Navigate]({
      type: "standard__navItemPage",
      attributes: {
        apiName: this.tabName,
      },
    });
  }
}

提示

lwc-recipes 存储库有很多导航示例。查看名为 的组件。nav*

更多页面类型示例

此代码显示了在 Lightning 中导航到不同类型页面的示例。这些示例演示如何创建不同类型的页面引用对象并导航到这些页面。您还可以将页面引用传递给 API,以检索解析为页面的 URL。[NavigationMixin.GenerateUrl](pageReference)promise

// navigationToPagesExample.js
import { LightningElement, wire } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class NavigationToPagesExample extends NavigationMixin(LightningElement) {
  navigateToObjectHome() {
    // Navigate to the Case object home page.
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Case",
        actionName: "home",
      },
    });
  }

  navigateToListView() {
    // Navigate to the Contact object's Recent list view.
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Contact",
        actionName: "list",
      },
      state: {
        // 'filterName' is a property on the page 'state'
        // and identifies the target list view.
        // It may also be an 18 character list view id.
        filterName: "Recent", // or by 18 char '00BT0000002TONQMA4'
      },
    });
  }

  navigateToNewRecordPage() {
    // Opens the new Account record modal
    // to create an Account.
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Account",
        actionName: "new",
      },
    });
  }

  navigateToRecordViewPage() {
    // View a custom object record.
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId: "a03B0000002tEurIAE",
        objectApiName: "namespace__ObjectName", // objectApiName is optional
        actionName: "view",
      },
    });
  }

  navigateToRecordEditPage() {
    // Opens the Account record modal
    // to view a particular record.
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId: "001B000000ZBz22IAD",
        objectApiName: "Account", // objectApiName is optional
        actionName: "edit",
      },
    });
  }

  navigateToRelatedList() {
    // Navigate to the CaseComments related list page
    // for a specific Case record.
    this[NavigationMixin.Navigate]({
      type: "standard__recordRelationshipPage",
      attributes: {
        recordId: "500xx000000Ykt4AAC",
        objectApiName: "Case",
        relationshipApiName: "CaseComments",
        actionName: "view",
      },
    });
  }

  navigateToTabPage() {
    // Navigate to a specific CustomTab.
    this[NavigationMixin.Navigate]({
      type: "standard__navItemPage",
      attributes: {
        // CustomTabs from managed packages are identified by their
        // namespace prefix followed by two underscores followed by the
        // developer name. E.g. 'namespace__TabName'
        apiName: "CustomTabName",
      },
    });
  }

  navigateToWebPage() {
    // Navigate to a URL
    this[NavigationMixin.Navigate](
      {
        type: "standard__webPage",
        attributes: {
          url: "http://salesforce.com",
        },
      },
      true, // Replaces the current page in your browser history with the URL
    );
  }
}

若要使用预填充的字段值启动记录的创建页面,请同时使用 and。lightning/pageReferenceUtilslightning/navigation

lightning/pageReferenceUtils 模块提供了 and 函数,用于将默认字段值编码为字符串并对其进行解码。将编码字符串分配给页面引用中的属性。encodeDefaultFieldValues()decodeDefaultFieldValues()pageReference.state.defaultFieldValuesstandard__objectPage

使用标准操作时,默认字段值会以字符串形式通过 URL 传递到对象,并为您处理重定向和替换。通过覆盖操作,您负责从 URL 解码默认字段值的字符串。

提示

在 lwc-recipes 示例存储库中,请参阅 navToNewRecordWithDefaults 组件。

使用标准操作启动具有默认字段值的联系人记录

此示例使用预填充的默认值启动记录的创建页。

此示例 HTML 包含用于创建联系人的链接。

<!-- navToNewRecordWithDefaults.html -->
<template>
  <lightning-button
    name="new-with-defaults"
    label="Go to New Contact with Defaults"
    class="slds-m-around_medium"
    onclick={navigateToNewContactWithDefaults}>
  </lightning-button>
</template>

要将默认字段值编码为字符串,请将它们传递给 。将编码的字符串分配给页面引用中的属性。encodeDefaultFieldValues()state.defaultFieldValues

// navToNewRecordWithDefaults.js
import { LightningElement } from "lwc";
import { NavigationMixin } from "lightning/navigation";
import { encodeDefaultFieldValues } from "lightning/pageReferenceUtils";

export default class NavToNewRecordWithDefaults extends NavigationMixin(LightningElement) {
  navigateToNewContactWithDefaults() {
    const defaultValues = encodeDefaultFieldValues({
      FirstName: "Morag",
      LastName: "de Fault",
      LeadSource: "Other",
    });

    console.log(defaultValues);

    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Contact",
        actionName: "new",
      },
      state: {
        defaultFieldValues: defaultValues,
      },
    });
  }
}

使用覆盖操作处理默认字段值

要使用自定义解决方案覆盖标准操作行为,请将模块包装在 Aura 组件中。

// auraOverrideWrapper.cmp
<aura:component implements="lightning:actionOverride">
  <c:lwcNewAccountOverride></c:lwcNewAccountOverride>
</aura:component>

该组件包括一个用于显示默认字段值的新客户记录页的窗体。lwcNewAccountOverride

<!-- lwcNewAccountOverride.html -->
<template>
  <lightning-record-edit-form object-api-name="Account" onsuccess={handleAccountCreated}>
    <lightning-input-field field-name="Name" value={dfv_AccountName}> </lightning-input-field>
    <lightning-input-field field-name="NumberOfEmployees" value={dfv_NumberOfEmployees}>
    </lightning-input-field>
    <lightning-input-field field-name="OwnerId" value={dfv_OwnerId}> </lightning-input-field>
    <lightning-input-field field-name="CustomCheckbox__c" value={dfv_CustomCheckbox}>
    </lightning-input-field>

    <lightning-button class="slds-m-top_small" type="submit" label="Create"> </lightning-button>
  </lightning-record-edit-form>
</template>

通过覆盖操作,您负责从 URL 解码默认字段值的字符串。

此示例用于从中读取默认字段值并获取编码的字符串。然后,它将字符串传递给 对其进行解码并处理帐户创建。CurrentPageReferencestatedecodeDefaultFieldValues()

此示例类似于使用 预填充字段值,不同之处在于此处的 是导航到表单时动态生成的。lightning-record-edit-formdefaultFieldValues

// lwcNewAccountOverride.js
import { LightningElement, wire } from "lwc";
import { CurrentPageReference } from "lightning/navigation";
import { decodeDefaultFieldValues } from "lightning/pageReferenceUtils";

export default class LwcNewAccountOverride extends LightningElement {
  @wire(CurrentPageReference)
  setCurrentPageReference(currentPageReference) {
    if (currentPageReference.state.defaultFieldValues) {
      const dfvObject = decodeDefaultFieldValues(currentPageReference.state.defaultFieldValues);
      this.dfv_AccountName = dfvObject.Name;
      this.dfv_NumberOfEmployees = dfvObject.NumberOfEmployees;
      // Handling required for boolean because we don't support boolean field types
      this.dfv_CustomCheckbox = dfvObject.CustomCheckbox__c === "true";
      this.dfv_OwnerId = dfvObject.OwnerId;
    }
  }

  dfv_AccountName = "";
  dfv_NumberOfEmployees = "";
  dfv_OwnerId = "";
  dfv_CustomCheckbox = false;

  // Run code when account is created
  handleAccountCreated() {}
}

重要

所有编码的默认字段值都以字符串形式传递到记录创建页面。例如,作为字符串而不是数字传递到页面中,布尔值 和 作为字符串传递。35000truefalse

若要使用此代码,请在“设置”中输入 。在 Account 对象上,创建一个具有 API 名称的复选框字段。然后选择“按钮”、“链接”和“操作”,并编辑“新建”操作。对于 Lightning Experience Override,选择 Lightning 组件,然后选择组件。Object ManagerCustomCheckbox__cc:auraOverrideWrapper

打开文件

要在 Lightning Experience 和 Salesforce 应用程序中打开一个或多个文件记录,请使用导航服务 .导航服务在 Lightning Experience 的模式对话框中打开一个或多个文件的预览,或在移动设备上的 Salesforce 应用程序中触发文件下载。lightning/navigation

使用页面引用打开文件

导航服务使用 PageReference,它描述一个页面,在本例中是一个文件。

使用带有 和 属性的页面引用。'type': 'standard__namedPage'pageNamefilePreview

命名页值支持 ContentDocument 和 ContentHubItem(外部文件)对象。Lightning Experience 和所有版本的移动应用程序都支持命名页面值。其他容器(例如 Lightning Components for Visualforce、Lightning Out 或 Experience Cloud 站点)不支持此功能。即使您在 Lightning Experience 或 Salesforce 移动应用程序中访问这些容器,页面值也不受支持。filePreviewfilePreview

示例:打开文件记录

此示例在 Lightning Experience 和 Salesforce 应用程序中打开带有 ID 的记录。069xx0000000001AAA

<!-- openFileSample.html -->
<template>
  <div>
    <a onclick={navigateToFiles}>Navigate To Files</a>
  </div>
</template>
// openFileSample.js
import { LightningElement } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class OpenFileSample extends NavigationMixin(LightningElement) {
  navigateToFiles() {
    this[NavigationMixin.Navigate]({
      type: "standard__namedPage",
      attributes: {
        pageName: "filePreview",
      },
      state: {
        recordIds: "069xx0000000001AAA,069xx000000000BAAQ",
        selectedRecordId: "069xx0000000001AAA",
      },
    });
  }
}

该属性是可供下载的所有记录 ID 的逗号分隔列表。recordIds

在 Lightning Experience 中,首先下载中指定的记录。用户可以通过单击应用程序中的箭头切换到其他记录。桌面文件预览器提供基于图像和 SVG 的多页办公文档预览、演示模式以及对文件操作(如共享、下载、上传和删除)的快速访问。selectedRecordId

在 Salesforce 应用程序中,触发事件时会下载单个文件。如果指定,则下载该文件。如果未指定,则下载列表中的第一个文件。根据设备的不同,将显示文件的本机预览。selectedRecordIdselectedRecordIdrecordIds

在 Visualforce Pages 中使用组件

将 Lightning Web 组件添加到您的 Visualforce 页面,以利用您在 Visualforce 中所做的任何投资。使用 Lightning Web 组件实现新功能,然后将其用于现有 Visualforce 页面。

重要

Lightning Components for Visualforce 基于 Lightning Out,这是一项强大而灵活的功能,可让您将 Aura 和 Lightning Web 组件嵌入到几乎任何网页中。当与 Visualforce 一起使用时,一些细节变得更加简单。例如,无需处理身份验证,也无需配置连接的应用。

在其他方面,使用 Visualforce 的 Lightning 组件就像使用 Lightning Out 一样。有关详细信息,请参阅闪电输出。

将 Lightning Web 组件添加到 Visualforce 页面有三个步骤。

步骤 1:添加 Visualforce JavaScript 库的 Lightning 组件

在 Visualforce 页面的开头添加。此组件加载 Lightning Components for Visualforce 使用的 JavaScript 文件。<apex:includeLightning/>

步骤 2:创建并引用独立的 Aura 依赖项应用

创建独立的 Aura 依赖项应用。使应用程序可全局访问并扩展 .声明对它使用的任何 Lightning 定义(如组件)的依赖关系。ltng:outApp

此示例 Aura 依赖项应用使用 Aura 标记来指示它使用标准 Lightning 组件 。<aura:dependency>lightning:button

<!--lwcvf.app-->
<aura:application access="GLOBAL" extends="ltng:outApp">
  <aura:dependency resource="lightning:button" />
</aura:application>

为您使用的每个 Lightning Web 组件添加一个标签。使用命名约定引用自定义 Lightning Web 组件。<aura:dependency><namespace:camelCaseComponentName>

注意

扩展范围会将 SLDS 资源添加到页面,以允许您的组件使用 Salesforce Lightning 设计系统 (SLDS) 进行样式设置。如果您不希望将 SLDS 资源添加到页面中,请改为从ltng:outAppltng:outAppUnstyled

若要在 Visualforce 页面上引用此应用程序,请使用以下 JavaScript 代码,其中 theNamespace 是应用程序的命名空间前缀。也就是说,您组织的命名空间,或提供应用程序的托管包的命名空间。

$Lightning.use("theNamespace:lwcvf", function () {});

如果应用是在组织中定义的(即,不在托管包中),请改用默认命名空间,如下例所示。如果您的组织未定义命名空间,则必须使用默认命名空间。c

有关创建 Lightning 依赖项应用程序的更多详细信息,请参阅 Lightning Out 依赖项。

步骤 3:在 Visualforce 页面上创建组件

最后,使用 将顶级组件添加到页面。$Lightning.createComponent(String type, Object attributes, String domLocator, function callback)

让我们看一个示例 Visualforce 页面,该页面使用上一个示例中的 创建。lightning:buttonlwcvf.app

<apex:page>
    <apex:includeLightning />

    <div id="lightningvf" />

    <script>
        $Lightning.use("c:lwcvf", function() {
          $Lightning.createComponent("lightning:button",
              { label : "Press Me!" },
              "lightningvf",
              function(cmp) {
                console.log("button was created");
                // do some stuff
              }
          );
        });
    </script>
</apex:page>

该调用将创建一个带有“Press Me!”标签的按钮。该按钮入到 ID 为 的 DOM 元素中。在页面上添加按钮并处于活动状态后,将调用回调函数并执行语句。回调接收创建的组件作为其唯一参数。在这个简单示例中,该按钮未配置为执行任何操作。$Lightning.createComponent()lightningvfconsole.log()

重要

您可以在一个页面上多次调用,但所有调用都必须引用同一个独立的 Aura 依赖项应用。$Lightning.use()

有关使用 和 的更多详细信息,请参阅闪电输出标记。$Lightning.use()$Lightning.createComponent()

浏览器第三方 Cookie

Lightning 组件在用户的浏览器中设置 Cookie。由于 Lightning 组件和 Visualforce 由不同的域提供,因此这些 Cookie 是“第三方”Cookie。您的用户必须在其浏览器设置中允许第三方 Cookie。有关更多详细信息,包括在 Safari 中禁用“阻止跨站点跟踪”设置的要求,请参阅闪电输出要求。

自定义选项卡

您可以将 Lightning Web 组件添加为 Lightning Experience 或 Salesforce 移动应用程序中的自定义选项卡。

为自定义选项卡配置组件

要将 Lightning Web 组件用作 Lightning Experience 或 Salesforce 移动应用程序中的自定义选项卡,请在组件的配置文件中添加选项卡目标。

componentName.js-meta.xml 文件定义组件的元数据值,包括允许在自定义选项卡中使用设置。将目标添加到组件的配置文件中。lightning__Tab

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
   <targets>
     <target>lightning__Tab</target>
  </targets>
</LightningComponentBundle>

配置选项卡目标后,将 Lightning Web 组件添加为 Lightning Experience 或 Salesforce 移动应用程序中的自定义选项卡。

在 Lightning Experience 应用程序中将组件添加为自定义选项卡

在自定义选项卡中提供 Lightning Web 组件,以便在桌面和 Salesforce 移动应用程序的 Lightning Experience 中访问该组件。

要配置要用作自定义选项卡的 Lightning Web 组件,请参阅为自定义选项卡配置组件。

要将您的组件包含在 Lightning Experience 应用程序中,并使其可供组织中的桌面和移动用户使用,请执行以下步骤。

  1. 为组件创建自定义选项卡。
    1. 在“设置”中,输入“快速查找”框,然后选择“选项卡”。Tabs
    2. 单击 Lightning 组件选项卡相关列表中的新建
    3. 选择要提供给用户的 Lightning 组件。
    4. 输入要在选项卡上显示的标签。
    5. 选择选项卡样式,然后单击下一步
    6. 当系统提示将选项卡添加到配置文件时,接受默认值,然后单击保存。您的 Lightning 组件现在可从桌面应用程序启动器的“所有项目”部分和 Salesforce 移动应用程序的“所有项目”导航菜单项获得。
  2. 将您的 Lightning 组件添加到 Lightning 应用程序的导航中。
    1. 在“设置”中,输入“快速查找”框,然后选择“应用程序管理器”。Apps
    2. 编辑现有应用程序或创建应用程序。
    3. 在“导航项目”屏幕上,从“可用项目”列表中选择您的 Lightning 组件选项卡,并将其移动到“所选项目”列表。
    4. 保存应用。
  3. 检查输出。
    1. 在桌面上的 Lightning Experience 或 Salesforce 移动应用程序中导航到应用程序启动器。
    2. 搜索自定义应用名称,然后单击它。
    3. 查看您添加的组件。

针对不同的外形规格配置组件

将组件配置为在以桌面格式 ()、手机格式 () 或两者呈现页面时显示在 Lightning 应用程序页面上。LargeSmall

在组件配置文件的部分中,使用标记集来声明组件支持页面类型的外形规格。<targetConfigs><supportedFormFactors>

如果未定义,则组件支持页面类型支持的外形规格。但是,我们建议为每个页面类型进行定义。<supportedFormFactors><supportedFormFactors>

应用和记录页面支持 和 外形规格。主页仅支持外形规格。LargeSmallLarge

应用和记录页面上的组件可以在手机和桌面上呈现,因为这些页面同时支持手机和桌面。主页上的组件只能在桌面上呈现,因为主页仅支持桌面。

此示例组件在三种页面类型上受支持:应用、记录和主页。在应用页面上,它配置为仅在具有外形规格的设备上呈现。当用户在具有外形规格的设备上查看应用页面时,该组件不会呈现。SmallLarge

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>42.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Best Component Ever</masterLabel>
    <description>This is a demo component.</description>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__AppPage">
            <property name="prop2" type="Boolean" />
            <supportedFormFactors>
                <supportedFormFactor type="Small" />
            </supportedFormFactors>
        </targetConfig>
        <targetConfig targets="lightning__RecordPage">
            <property name="prop1" type="String" />
            <supportedFormFactors>
                <supportedFormFactor type="Large" />
            </supportedFormFactors>
        </targetConfig>
        <targetConfig targets="lightning__HomePage">
            <property name="prop3" type="Integer" />
            <supportedFormFactors>
                <supportedFormFactor type="Large" />
            </supportedFormFactors>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

注意

在 Lightning 页面上使用组件后,您只能增加该组件支持的外形规格,而不能减小它们。

使组件了解其上下文

组件可以知道其记录上下文、对象上下文及其在 Lightning 应用程序生成器中的区域宽度。

使组件了解其记录上下文

在某些用例中,让组件了解其记录上下文会很有帮助。例如,您希望提供记录上下文,以便组件可以在查看的记录页面上返回和显示子记录信息。要使组件了解其对象上下文,请使用 Lightning 记录页面上的属性。然后,该页将该属性设置为当前记录的 ID。recordId

提示

lwc-recipes 存储库有一个 wireGetRecordDynamicContact 组件,该组件返回正在查看的联系人记录的一些数据。

在 Lightning Experience 中访问记录上下文

在组件的 JavaScript 类中,使用修饰器创建公共属性。@apirecordId

// testClass.js
import { LightningElement, api } from "lwc";
export default class TestClass extends LightningElement {
  @api recordId;
}

在 Lightning Experience 或移动应用程序的记录上下文中调用组件时,recordId 设置为记录的 18 个字符的 ID,例如:。001xx000003DGSWAA4

重要

仅当您在显式记录上下文中放置或调用组件时,才会自动设置 。在所有其他情况下,不会设置 ,并且组件不能依赖于它。在这种情况下,您可以设置自己。例如,用于快速操作的组件在记录页面上使用时,可以显式设置是否需要访问记录 ID。recordIdrecordIdrecordIdrecordId

在 Experience Builder 站点中访问记录上下文

Experience Builder 站点不会自动绑定到组件的模板。recordId

包含修饰器以在组件上创建公共属性后,在组件的文件中添加表达式。参数中指定的所有页面类型都可以访问记录 ID。@apirecordIdrecordId*.js-meta.xmltargets

<targetConfigs>
  <targetConfig targets="lightningCommunity__Default">
    <property
      name="recordId"
      type="String"
      label="Record Id"
      description="Automatically bind the page's record id to the component variable"
      default="{!recordId}"
    />
  </targetConfig>
</targetConfigs>

在Experience Builder站点的记录上下文中调用组件时,表达式将设置为记录的18个字符的ID。"{!recordId}"

使组件了解其对象上下文

在某些用例中,使组件了解其对象上下文会很有帮助。例如,您希望提供对象上下文,以便组件可以根据页面上正在查看的对象返回一些信息。要使组件了解其对象上下文,请使用 Lightning 记录页面上的属性。然后,页面将该属性设置为当前对象的 API 名称。objectApiName

提示

lwc-recipes 存储库有一个 wireGetObjectInfo 组件,该组件返回所选对象的对象信息。

在 Lightning Experience 中访问对象上下文

在组件的 JavaScript 类中,使用修饰器创建公共属性。@apiobjectApiName

// testClass.js
import { LightningElement, api } from "lwc";
export default class TestClass extends LightningElement {
  @api objectApiName;
}

在 Lightning Experience 或移动应用程序的记录上下文中调用组件时,将设置为与正在查看的记录关联的对象的 API 名称,例如:。objectApiNameWarehouse__c

重要

仅当您在显式记录上下文中放置或调用组件时,才会设置 。在所有其他情况下,未设置 ,并且组件不应依赖于它。objectApiNameobjectApiName

在Experience Builder Sites中访问对象上下文

Experience Builder 站点不会自动绑定到组件的模板。objectApiName

包含修饰器以在组件上创建公共属性后,在组件的文件中添加表达式。参数中指定的所有页面类型都可以访问对象名称。@apiobjectApiNameobjectApiName*.js-meta.xmltargets

注意

此方法仅适用于 在路由中 的组件。{!objectApiName}

<targetConfigs>
  <targetConfig targets="lightningCommunity__Default">
    <property
      name="objectApiName"
      type="String"
      label="Object Name"
      description="Automatically bind the page's object name to the component variable"
      default="{!objectApiName}"
    />
  </targetConfig>
</targetConfigs>

在Experience Builder站点的对象上下文中调用组件时,表达式将设置为对象的18个字符的ID。objectApiName

使组件具有宽度感知能力

当您在 Lightning 应用程序构建器中将组件添加到页面上的区域时,请使用将区域的宽度传递给组件。然后,通过一些战略性的 CSS,你可以告诉组件在运行时以不同的方式在不同的区域中呈现。@api flexipageRegionWidth

例如,列表视图组件在大区域中的呈现方式与在小区域中的呈现方式不同,因为它是宽度感知组件。

在组件的 JavaScript 类中,使用修饰器创建公共属性。此属性接收组件在页面上所在的区域的宽度值。@apiflexipageRegionWidth

// testClass.js
import { LightningElement, api } from "lwc";

export default class TestClass extends LightningElement {
  @api flexipageRegionWidth;
}

使用 HTML 模板中的属性。当值更改时,组件将重新呈现。flexipageRegionWidthflexipageRegionWidth

<!-- testClass.html -->
<template>
  <div class={flexipageRegionWidth}>...</div>
</template>

使用 CSS 定义组件在以不同区域宽度呈现时的行为。有效的 CSS 类值为 、 和 。此示例 CSS 代码段告诉组件在大型区域中时以红色背景呈现。当它位于一个小区域时,它以蓝色背景呈现。SMALLMEDIUMLARGE

/* testClass.css */

div.LARGE {
  background: red;
  ...;
}
div.SMALL {
  background: blue;
  ...;
}

快速操作

快速操作使用户能够在 Salesforce 中执行更多操作。通过自定义快速操作,您可以方便地访问最重要的信息,从而使用户的导航和工作流程尽可能顺畅。快速操作可以在记录页面上调用自定义 Lightning Web 组件。

配置组件时,可以选择在模式窗口中显示它,也可以选择无头执行其自定义代码。例如,快速操作可以打开自定义 Lightning Web 组件,其中包含允许用户创建或更新记录上特定字段的表单。快速操作还可以执行导航到另一个页面或调度事件的 Lightning Web 组件代码。

注意

Lightning Web 组件仅支持作为 Lightning Experience 中的快速操作。Salesforce 移动应用程序不支持使用 Lightning Web 组件作为快速操作。

配置组件以执行快速操作

要使用 Lightning Web 组件作为快速操作,请定义组件的元数据。

屏幕快速操作和无头快速操作

LWC 快速操作有两种类型:屏幕快速操作和无头快速操作

  • 屏幕快速操作在模式窗口中显示组件。请参阅创建屏幕快速操作。
  • 无外设快速操作执行您在方法中提供的自定义代码。请参阅创建 Headless 快速操作。@api invoke()

注意

您只能将 Lightning Web 组件用作记录页面上的快速操作。您不能将 Lightning Web 组件用作全局快速操作。

在配置文件中定义组件元数据

组件的项目文件夹必须包含定义组件元数据值的 componentName.js-meta.xml 配置文件。若要将组件用作快速操作,请按照以下步骤配置文件。

  1. 在 中,添加为 a 以将 Lightning Web 组件指定为记录页面上的快速操作。targetslightning__RecordActiontarget
  2. 添加 并设置为 。targetConfigtargetslightning__RecordAction
  3. 设置为 或 选择快速操作类型。如果未指定 ,则快速操作默认为屏幕操作。actionTypeScreenActionActionactionType

此配置文件定义屏幕操作。

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>52.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__RecordAction</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__RecordAction">
      <actionType>ScreenAction</actionType>
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

此配置文件定义了无头操作。

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>52.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__RecordAction</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__RecordAction">
      <actionType>Action</actionType>
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

请参阅 XML 配置文件元素的完整列表。

在 Salesforce 设置中创建快速操作

在 Salesforce 设置中,通过“对象管理器”页面创建特定于对象的操作。然后将该操作添加到页面布局的 Salesforce Mobile 和 Lightning Experience 操作部分。请参阅 Salesforce 帮助中的快速操作。

注意

Salesforce 移动应用程序不支持使用 Lightning Web 组件作为快速操作。

创建屏幕快速操作

屏幕快速操作将显示在模式窗口中。提供您自己的标记或使用该组件,以实现基于 Lightning Design System 的一致用户界面。lightning-quick-action-panel

要使组件用作屏幕快速操作,请配置目标。请参阅配置组件以执行快速操作。

与记录页面上的其他 Lightning Web 组件不同,LWC 快速操作不会传入 .如果需要访问 ,请在代码中设置 的值。recordIdconnectedCallback()recordIdrecordId

_recordId;
set recordId(recordId) {
    if (recordId !== this._recordId) {
        this._recordId = recordId;

打开和关闭模式窗口

屏幕快速操作可在模式窗口中打开 Lightning Web 组件。要以编程方式关闭模式窗口,例如,要创建“取消”按钮,请生成调度自定义事件的 UI。从模块导入事件。CloseActionScreenEventlightning/actions

import { CloseActionScreenEvent } from "lightning/actions";

以下各节包含完整的代码示例。

注意

如果使用自定义页脚按钮构建屏幕快速操作,则按 X 仅关闭模式,则没有挂钩在关闭时执行其他逻辑。如果屏幕快速操作具有在“取消”时执行的逻辑,则在面板关闭时将绕过该逻辑。

使用 lightning-quick-action-panel 实现一致的 UI

要提供一致的 Salesforce UI,请将 Lightning Web 组件包装在 lightning-quick-action-panel 组件中,该组件提供与 Salesforce Lightning Design System 中的模式蓝图一致的页眉、正文和页脚。

<template>
  <lightning-quick-action-panel header="My action">
    Here's some content for the modal body.

    <div slot="footer">
      <lightning-button variant="neutral" label="Cancel"></lightning-button>
      <lightning-button variant="brand" label="Save" class="slds-m-left_x-small"></lightning-button>
    </div>
  </lightning-quick-action-panel>
</template>

在模态主体中创建表单

创建模态主体的一种方法是将组件与由组件填充的字段值一起使用。取消和提交按钮必须嵌套在组件中,因此使用此方法时不需要页脚槽。lightning-record-edit-formlightning-input-fieldlightning-record-edit-form

本示例创建一个窗体,用于填充不带页脚的 name 和 phone 字段。它呈现一个模态窗口,其标题包含文本“编辑字段操作”。lightning-record-edit-form

<template>
  <lightning-quick-action-panel header="Edit Fields Action">
    <lightning-record-edit-form
      record-id={recordId}
      object-api-name={objectApiName}
      onsuccess={handleSuccess}>
      <lightning-input-field field-name="Name"></lightning-input-field>
      <lightning-input-field field-name="Phone"></lightning-input-field>
      <lightning-button variant="neutral" label="Cancel"></lightning-button>
      <lightning-button variant="brand" class="slds-m-left_x-small" label="Save" type="submit">
      </lightning-button>
    </lightning-record-edit-form>
  </lightning-quick-action-panel>
</template>

当用户单击提交按钮时,将调用事件处理程序。处理程序使用该函数关闭模式窗口。handleSuccessCloseActionScreenEvent

import { LightningElement, api } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import { CloseActionScreenEvent } from "lightning/actions";

export default class QuickEditFormExample extends LightningElement {
  @api recordId;
  @api objectApiName;

  handleSuccess(e) {
    // Close the modal window and display a success toast
    this.dispatchEvent(new CloseActionScreenEvent());
    this.dispatchEvent(
      new ShowToastEvent({
        title: "Success",
        message: "Record updated!",
        variant: "success",
      }),
    );
  }
}

在页脚中创建带有按钮的自定义窗体

您可以使用 和 组件在模态主体中创建表单。使用此方法时,请使用组件的页脚槽来包含按钮。lightning-inputlightning-buttonlightning-quick-action-panel

此示例创建一个窗体,用于对联系人记录执行与上一示例类似的快速操作,并在页脚中使用按钮,因为它不使用记录窗体组件。该字段显示使用电线适配器的初始值。getRecord

<lightning-quick-action-panel header="Quick Contact Edit">
  <template lwc:if={contact.data}>
    <lightning-input
      label="First Name"
      value={firstname}
      class="slds-m-bottom_x-small">
    </lightning-input>
    <lightning-input
      label="Last Name"
      value={lastname}
      onchange={handleLastNameChange}
      class="slds-m-bottom_x-small"
      required>
    </lightning-input>
    <lightning-input
      label="Phone"
      type="tel"
      value={phone}
      class="slds-m-bottom_x-small">
    </lightning-input>
  </template>
  <div slot="footer">
    <lightning-button variant="neutral" label="Cancel" onclick={handleCancel}></lightning-button>
    <lightning-button
      variant="brand"
      class="slds-m-left_x-small"
      label="Save"
      type="submit"
      onclick={handleSubmit}
      disabled={disabled}>
    </lightning-button>
  </div>
</lightning-quick-action-panel>

如果“姓氏”字段为空,则“保存”按钮将被禁用。单击“保存”按钮将关闭模式窗口,如果保存成功,则显示 Toast。若要保存记录更改,请调用 updateRecord(recordInput, clientOptions)。

import { LightningElement, api, wire } from "lwc";
import { getRecord, getFieldValue } from "lightning/uiRecordApi";
import { updateRecord } from "lightning/uiRecordApi";
import { CloseActionScreenEvent } from "lightning/actions";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import FNAME_FIELD from "@salesforce/schema/Contact.FirstName";
import LNAME_FIELD from "@salesforce/schema/Contact.LastName";
import PHONE_FIELD from "@salesforce/schema/Contact.Phone";

const FIELDS = [FNAME_FIELD, LNAME_FIELD, PHONE_FIELD];

export default class QuickEditExample extends LightningElement {
  disabled = false;
  @api recordId;
  @api objectApiName;

  @wire(getRecord, { recordId: "$recordId", fields: FIELDS })
  contact;

  get firstname() {
    return getFieldValue(this.contact.data, FNAME_FIELD);
  }

  get lastname() {
    return getFieldValue(this.contact.data, LNAME_FIELD);
  }

  get phone() {
    return getFieldValue(this.contact.data, PHONE_FIELD);
  }

  handleCancel(event) {
    // Add your cancel button implementation here
    this.dispatchEvent(new CloseActionScreenEvent());
  }

  handleLastNameChange(event) {
    // Display field-level errors if last name field is empty.
    if (!event.target.value) {
      event.target.reportValidity();
      this.disabled = true;
    } else {
      this.disabled = false;
    }
  }

  handleSubmit(e) {
    // Add your updateRecord implementation

    // Close the modal window and display a success toast
    this.dispatchEvent(new CloseActionScreenEvent());
    this.dispatchEvent(
      new ShowToastEvent({
        title: "Success",
        message: "Record updated!",
        variant: "success",
      }),
    );
  }
}

获取有关主页的信息

您可以使用标准 LWC 功能获取有关当前页面的信息,包括来自导航服务的页面引用、记录 ID 和当前记录的对象 API 名称。

要返回页面引用,请从 lightning/navigation 导入。请参阅导航到页面、记录和列表。CurrentPageReference

若要获取记录 ID 和对象 API 名称,请公开 and 作为属性。请参阅使组件了解其记录上下文和使组件了解其对象上下文。recordIdobjectApiName

此示例显示当前记录的记录 ID 和对象 API 名称。它还返回当前页面引用,该引用描述当前页面及其状态。

<template>
  <p>These two fields are auto-populated based on the record context:</p>
  <p>RecordId: <i>{recordId}</i>, objectApiName: <i>{objectApiName}</i></p>
  <p>{pageRefString}</p>
</template>
import { LightningElement, api, wire } from "lwc";
import { CurrentPageReference } from "lightning/navigation";

export default class RecordContextAction extends LightningElement {
  @api recordId;
  @api objectApiName;

  @wire(CurrentPageReference)
  pageRef;

  get pageRefString() {
    return JSON.stringify(this.pageRef);
  }
}

创建 Headless 快速操作

无头快速操作在 Lightning Web 组件中执行自定义代码。与屏幕操作不同,无头操作不会打开模式窗口。

要使您的组件用作无外设快速操作,请配置目标。请参阅配置组件以执行快速操作。

与记录页面上的其他 Lightning Web 组件不同,LWC 快速操作不会传入 .如果需要访问 ,请在代码中设置 的值。recordIdconnectedCallback()recordIdrecordId

_recordId;
set recordId(recordId) {
    if (recordId !== this._recordId) {
        this._recordId = recordId;

实现 invoke()

在您的 Lightning Web 组件中,始终公开为无头快速操作的公共方法。每次触发快速操作时,都会执行该方法。invoke()invoke()

import { LightningElement, api } from "lwc";

export default class HeadlessSimple extends LightningElement {
  @api invoke() {
    console.log("Hi, I'm an action.");
  }
}

为您的 Lightning Web 组件创建一个空模板。

<template> </template>

若要防止在长时间运行的操作中多次并行执行快速操作,请添加内部布尔标志。

的返回类型为 。返回 a 会使方法异步,但返回的方法将被忽略。invoke()voidPromisePromise

此代码使用布尔标志来阻止双重执行,并使用 a 来等待完成。即使返回类型为 ,代码也会异步执行。Promisesleepvoid

import { LightningElement, api } from "lwc";

export default class HeadlessAsync extends LightningElement {
  isExecuting = false;

  @api async invoke() {
    if (this.isExecuting) {
      return;
    }

    this.isExecuting = true;
    await this.sleep(2000);
    this.isExecuting = false;
  }

  sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
}

导航

要导航到 Lightning Experience 中的其他页面、记录或列表,请使用导航服务。

此示例导航到联系人主页。

import { LightningElement, api } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class navigateToRecordAction extends NavigationMixin(LightningElement) {
  @api invoke() {
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Contact",
        actionName: "home",
      },
    });
  }
}

请参阅导航到页面、记录和列表。

调度事件

您可以通过快速操作调度自定义事件。此示例使用模块提供的事件按顺序调度两个 Toast。lightning/platformShowToastEvent

import { LightningElement, api } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";

export default class DispatchEventAction extends LightningElement {
  @api async invoke() {
    let event = new ShowToastEvent({
      title: "I am a headless action!",
      message: "Hi there! Starting...",
    });
    this.dispatchEvent(event);

    await this.sleep(2000);

    event = new ShowToastEvent({
      title: "I am a headless action!",
      message: "All done!",
    });
    this.dispatchEvent(event);
  }

  sleep(ms) {
    // eslint-disable-next-line @lwc/lwc/no-async-operation
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
}

请参阅 Toast 通知和与事件通信。

将电子邮件创建为快速操作

从自定义组件中的按钮启动包含预填充内容的电子邮件编辑器。使用 和 组件创建 QuickAction (Global) Send Email 操作,该操作将打开包含预填充字段值的电子邮件草稿。lightning-navigationlightning-page-reference-utils

在组件的 HTML 文件中,使用 定义导航服务,使用 定义页面引用实用程序,使用 定义操作按钮。lightning-navigationlightning-page-reference-utilslightning-button

在此示例中,该函数在单击时触发,并使用主题和正文文本预填充电子邮件编辑器。handleClick

要在电子邮件编辑器中包含默认文本,请使用该函数。将结果添加到传递到有效负载的页面引用中的属性中。若要使用组件的输入填充电子邮件,请将字段值传递到函数中。encodeDefaultFieldValuesdefaultFieldValuesfieldOverrideencodeDefaultFieldValues

确保您在函数中指定的字段在“发送电子邮件”全局操作的布局中不是只读的。在此示例中,如果“HTML 正文”和“主题”字段为只读,则电子邮件草稿不包含这些字段的预填充文本。encodeDefaultFieldValues

在 HTML 文件中添加一个触发事件处理程序的按钮。

<div>
  <lightning-button
    variant="neutral"
    label="Send an Email"
    onclick={handleClick}>
  </lightning-button>
</div>

然后添加事件处理程序。

import { LightningElement } from "lwc";
import { NavigationMixin } from "lightning/navigation";
import { encodeDefaultFieldValues } from "lightning/pageReferenceUtils";

export default class EmailQuickAction2 extends NavigationMixin(LightningElement) {
  handleClick() {
    var pageRef = {
      type: "standard__quickAction",
      attributes: {
        apiName: "Global.SendEmail",
      },
      state: {
        recordId: "00QB000000BLjUrMAL",
        defaultFieldValues: encodeDefaultFieldValues({
          HtmlBody: "Pre-populated text for the email body.",
          Subject: "Pre-populated Subject of the Email",
        }),
      },
    };

    this[NavigationMixin.Navigate](pageRef);
  }
}

在独立 Aura 应用程序中使用组件

您可以在独立的 Aura 应用程序中使用自定义 Lightning Web 组件。独立应用程序在开发人员控制台中也称为 Lightning 应用程序。

引用 Lightning Web 组件的命名约定是 ,这与在 Aura 组件中使用 Lightning Web 组件的命名约定相同。<namespace:camelCaseComponentName>

这个独立的 Aura 应用程序使用默认命名空间中的 Lightning Web 组件。myComponentc

<!-- sampleApp.app -->
<aura:application>
  <c:myComponent />
</aura:application>

为 Outlook 和 Gmail 集成创建组件

创建 Lightning App Builder 中提供的自定义 Lightning Web 组件,以添加到 Outlook 和 Gmail 集成的电子邮件应用程序窗格中。

在组件的配置文件中,添加目标并设置为 。lightning__Inbox<isExposed>true

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <isExposed>true</isExposed>
    <apiVersion>46.0</apiVersion>
    <targets>
        <target>lightning__Inbox</target>
    </targets>
    <description>Sample Email Application Pane</description>
</LightningComponentBundle>

目标将属性添加到组件中。在组件的 JavaScript 文件中声明属性。此示例声明它在模板中使用的三个属性。lightning__Inbox

// sampleEmailAppPane.js

import { LightningElement, api } from "lwc";

export default class SampleEmailAppPane extends LightningElement {
  @api messageBody;
  @api subject;
  @api people;
}

访问组件模板中的属性。

<!-- sampleEmailAppPane.html -->

<template>
  <div>Sample Email Application Pane</div>

  <template for:each={people.from} for:item="from">
    <div key={from.email}>{from.email}</div>
  </template>

  <template for:each={people.to} for:item="to">
    <div key={to.email}>{to.email}</div>
  </template>

  <div>{subject}</div>

  <div>{messageBody}</div>
</template>

注意

通常,要允许用户在 Lightning App Builder 中设置组件的属性,您必须将该属性添加到组件的配置文件中。但是,除非要设置其默认值,否则无需向组件的配置文件添加属性。lightning__Inbox

日期

数据类型:对象

事件的日期。

dates: {
  start: 'value',
  end: 'value'
}

支持的来源:event

电子邮件

数据类型:数组

简单数组中收件人的电子邮件地址。如果您不关心地址是在“收件人”、“发件人”或“抄送”字段中,或者不关心收件人是哪种类型的与会者,请使用此属性。

["abc@salesforce.com", "def@salesforce.com"];

支持的来源: ,emailevent

位置

数据类型:字符串

事件的位置。

支持的来源:event

messageBody(消息正文)

数据类型:字符串

纯文本电子邮件的邮件正文。不保留 HTML 格式。

支持的来源: ,emailevent

模式

数据类型:字符串

访问模式。可能的值:、'view''edit'

支持的来源: ,emailevent

数据类型:对象

当前电子邮件或事件中收件人的电子邮件地址。人员属性的形状会根据源属性的值而变化。当该属性设置为 时,对象将包含这些元素。sourceemailpeople

{
  to: [
    {
      name: 'name',
      email: 'email'
    }
  ],
  cc: [
    {
      name: 'name',
      email: 'email'
    }
  ],
  from: [
    {
      name: 'senderName',
      email: 'senderEmail'
    }
  ]
}

当该属性设置为 时,对象将包含这些元素。sourceeventpeople

{
  requiredAttendees: [
    {
      name: 'attendeeName',
      email: 'email'
    }
  ],
  optionalAttendees: [
    {
      name: 'optAttendeeName',
      email: 'email'
    }
  ],
  organizer: [
    {
      name: 'organizerName',
      email: 'senderEmail'
    }
  ]
}

支持的来源: ,emailevent

数据类型:字符串

可能的值:、'email''event'

支持的来源: ,emailevent

主题

对象类型:字符串

电子邮件的主题。

支持的来源: ,emailevent

注意

若要确保自定义组件在电子邮件应用程序窗格中正确显示,请使其能够调整为可变宽度。请参阅使组件具有宽度感知能力。

在 Flow Builder 中自定义操作和屏幕组件 UI

开发一个自定义属性编辑器,当管理员在 Flow Builder 中配置自定义屏幕组件或可调用操作时,该编辑器可为其提供简化的 UI。自定义属性编辑器是一个 Lightning Web 组件,它提供用于输入输入值的自定义 UI。

将自定义属性编辑器与标准属性编辑器进行比较

如果没有自定义属性编辑器,当管理员在 Flow Builder 中配置自定义流屏幕组件或可调用操作时,UI 由组件输入值的文本框或组合框组成。自定义属性编辑器的 UI 可以由任何输入组件组成,并且可以使用自定义样式。此示例显示了一个没有自定义属性编辑器的自定义流屏幕组件。该组件显示将数据传递到流中的输入属性的文本框和组合框。

相反,请创建一个自定义属性编辑器,为管理员提供简化的体验。此示例显示了一个自定义流屏幕组件,该组件具有自定义属性编辑器,该编辑器使用自定义标签和滑块组件作为输入值。

示例:可调用操作的自定义属性编辑器

此示例创建一个可调用操作及其自定义属性编辑器。在 Flow Builder 中,管理员为“发送 HTML 电子邮件”可调用操作设置输入值。当用户运行流时,可调用操作会发送电子邮件。

此 Apex 类文件定义了可作为可调用操作运行的方法及其输入变量。注释标识可作为可调用操作运行的可调用方法。注释标识可调用方法使用的变量。sendEmails@InvocableMethod@InputVariable

可调用方法在修饰符中注册自定义属性编辑器。除非组织具有自定义命名空间,否则命名空间。如果组织具有自定义命名空间,请使用该命名空间注册自定义属性编辑器。在此示例中,自定义属性编辑器的名称为 。configurationEditorcc-html-email-editor

// HtmlEmailAction.cls
global class HtmlEmailAction {
    global class EmailActionRequest {
        @InvocableVariable
        global String senderName;

        @InvocableVariable
        global String replyToEmail;

        @InvocableVariable
        global String recipientName;

        @InvocableVariable
        global String sendToEmail;

        @InvocableVariable
        global String subject;

        @InvocableVariable
        global String htmlBody;
    }

    global class EmailActionResult {
        @InvocableVariable
        global Boolean isSuccess;

        @InvocableVariable
        global String errorMessage;
    }

    @InvocableMethod(label='Send HTML Email' configurationEditor='c-html-email-editor')
    global static List<EmailActionResult> sendEmails(List<EmailActionRequest> requests) {
        List<EmailActionResult> results = new List<EmailActionResult>();

        for(EmailActionRequest request : requests){
            results.add(sendEmail(request));
        }

        return results;
    }

    public static EmailActionResult sendEmail(EmailActionRequest request) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        String[] sendToEmail = new String[]{ request.sendToEmail };
        mail.setToAddresses(sendToEmail);
        mail.setSenderDisplayName(request.senderName);
        mail.setReplyTo(request.replyToEmail);
        mail.setSubject(request.subject);
        mail.setHtmlBody(request.htmlBody);
        mail.setOptOutPolicy('FILTER');

        Messaging.SingleEmailMessage[] messages = new List<Messaging.SingleEmailMessage>();
        messages.add(mail);

        Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
        EmailActionResult emailActionResult = new EmailActionResult();

        for(Messaging.SendEmailResult result :results) {
            if(result.IsSuccess()) {
                emailActionResult.isSuccess = true;
            } else {
                emailActionResult.isSuccess = false;
                Messaging.SendEmailError[] errors = result.getErrors();
                if (errors.size() > 0 ){
                    emailActionResult.errorMessage = errors[0].getMessage();
                }
            }
        }

        return emailActionResult;
    }
}

这些 HTML、CSS、JavaScript 和配置文件定义操作的自定义属性编辑器。

HTML 模板定义 Flow Builder 中自定义属性编辑器的 UI。

<!--htmlEmailEditor.html-->
<template>
  <div class="slds-m-bottom_x-small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">
      Sender Information
    </h2>

    <div class="slds-p-around_xx-small lgc-bg">
      <lightning-input
        type="text"
        label="Sender Name"
        placeholder="Enter sender name here..."
        value={senderName}
        onchange={handleSenderNameChange}
      >
      </lightning-input>

      <lightning-input
        type="email"
        label="Reply-To Email Address"
        placeholder="Enter reply-to email address here..."
        value={replyToEmail}
        onchange={handleReplyToEmailChange}
      >
      </lightning-input>
    </div>
  </div>

  <div class="slds-m-bottom_x-small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">
      Recipient Information
    </h2>

    <div class="slds-p-around_xx-small lgc-bg">
      <lightning-input
        type="text"
        label="Recipient Name"
        placeholder="Enter recipient name here..."
        value={recipientName}
        onchange={handleRecipientNameChange}
      >
      </lightning-input>

      <lightning-input
        type="email"
        label="Send-To Email Address"
        placeholder="Enter send-to email address here..."
        value={sendToEmail}
        onchange={handleSendToEmailChange}
        required
      >
      </lightning-input>
    </div>
  </div>

  <div class="slds-m-top_small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">Subject and Body</h2>

    <div class="slds-p-around_xx-small lgc-bg">
      <lightning-input
        type="text"
        label="Subject"
        placeholder="Enter subject here..."
        value={subject}
        onchange={handleSubjectChange}
      >
      </lightning-input>

      <div class="row">
        <lightning-textarea
          name="body"
          label="HTML Body"
          placeholder="Enter html body here..."
          value={htmlBody}
          onchange={handleHtmlBodyChange}
        >
        </lightning-textarea>
      </div>
    </div>
  </div>
</template>

此示例显示自定义属性编辑器 UI。

初始化自定义属性编辑器后,JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中更改值时,自定义属性编辑器会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// htmlEmailEditor.js
import { LightningElement, api } from "lwc";
export default class HtmlEmailEditor extends LightningElement {
  @api
  inputVariables;

  get senderName() {
    const param = this.inputVariables.find(({ name }) => name === "senderName");
    return param && param.value;
  }

  get replyToEmail() {
    const param = this.inputVariables.find(({ name }) => name === "replyToEmail");
    return param && param.value;
  }

  get recipientName() {
    const param = this.inputVariables.find(({ name }) => name === "recipientName");
    return param && param.value;
  }

  get sendToEmail() {
    const param = this.inputVariables.find(({ name }) => name === "sendToEmail");
    return param && param.value;
  }

  get subject() {
    const param = this.inputVariables.find(({ name }) => name === "subject");
    return param && param.value;
  }

  get htmlBody() {
    const param = this.inputVariables.find(({ name }) => name === "htmlBody");
    return param && param.value;
  }

  @api validate() {
    const validity = [];
    if (
      !this.isValidEmailAddress(this.sendToEmail) ||
      !this.isValidEmailAddress(this.replyToEmail)
    ) {
      validity.push({
        key: "SendToAddress",
        errorString: "You have entered an invalid email format.",
      });
    }
    return validity;
  }

  isValidEmailAddress(email) {
    const emailRegex = /^\w+([\.-]?\w+)+@\w+([\.:]?\w+)+(\.[a-zA-Z0-9]{2,3})+$/;
    return emailRegex.test(email);
  }

  handleSenderNameChange(event) {
    this.handleChange(event, "senderName");
  }

  handleReplyToEmailChange(event) {
    this.handleChange(event, "replyToEmail");
  }

  handleRecipientNameChange(event) {
    this.handleChange(event, "recipientName");
  }

  handleSendToEmailChange(event) {
    this.handleChange(event, "sendToEmail");
  }

  handleSubjectChange(event) {
    this.handleChange(event, "subject");
  }

  handleHtmlBodyChange(event) {
    this.handleChange(event, "htmlBody");
  }

  handleChange(event, name) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name,
          newValue,
          newValueDataType: "String",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 和 接口。inputVariablesvalidate

初始化自定义属性编辑器后,从 Flow Builder 接收可调用操作中输入变量的值。inputVariables

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[
  {
    name: "senderName",
    value: "Test Inc",
    valueDataType: "String",
  },
];

方法(如 和 )获取每个输入变量,以便在自定义属性编辑器中使用。getget senderName()get replyToEmail()value

当管理员在 Flow Builder 的屏幕编辑器 UI 中单击“完成”时,Flow Builder 会在自定义属性编辑器中评估函数。如果函数返回 和 数据结构,则屏幕编辑器会显示错误数,并阻止管理员在屏幕编辑器中保存更改。validatekeyerrorString

注意

Flow Builder 仅显示错误数。若要显示错误字符串,请在方法中编写代码。有关更多信息,请参见自定义属性编辑器 JavaScript 接口。validate

当管理员在自定义属性编辑器中输入输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleChangeconfiguration_editor_input_value_changed

下面是 的配置文件。htmlEmailEditor

<!--htmlEmailEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>49.0</apiVersion>
    <!--isExposed can be true or false-->
    <isExposed>true</isExposed>
</LightningComponentBundle>

示例:屏幕组件的自定义属性编辑器

此示例为显示卷的自定义流屏幕组件创建自定义属性编辑器。管理员使用卷组件的自定义属性编辑器中的滑块设置卷。当用户运行流程时,流程屏幕会显示管理员设置的音量级别。

以下 HTML、JavaScript 和配置文件定义自定义流屏幕组件。volume

<!--volume.html-->
<template>
  <div>
    <h1 class="slds-text-heading_medium">Volume</h1>
  </div>

  <div class="slds-p-top_xxx-small">
    <p>
      Your selected volume is:
      <lightning-formatted-number value={volume}></lightning-formatted-number>
    </p>
  </div>
</template>

JavaScript 类定义一个公共属性。volume

// volume.js
import { LightningElement, api } from "lwc";

export default class Volume extends LightningElement {
  @api volume;
}

要在 Flow Builder 中公开公共属性,请在配置文件中定义它:。该特性确定属性是否可以接收来自流的输入。本示例中使用的默认值为 。若要使属性仅可用于输入或输出,请将该特性设置为 或 。volume<property name="volume" type="Integer"/>roleinputAndOutputroleinputOnlyoutputOnly

在配置文件中,使用属性注册自定义属性编辑器:。除非组织具有自定义命名空间,否则请使用命名空间。如果组织具有自定义命名空间,请使用该命名空间。configurationEditor<targetConfig targets="lightning__FlowScreen" configurationEditor="c-volume-editor">c

<!-- volume.js-meta.xml-->
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>49.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <masterLabel>Volume</masterLabel>
  <targetConfigs>
    <targetConfig targets="lightning__FlowScreen" configurationEditor="c-volume-editor">
      <property name="volume" type="Integer"/>
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

以下 HTML、JavaScript 和配置文件定义组件的自定义属性编辑器。volume

自定义属性编辑器的 HTML 模板定义 UI,该 UI 使用滑块基础 Lightning Web 组件。

<!--volumeEditor.html-->
<template>
  <div class="slds-p-around_xx-small">
    <lightning-slider label="Volume" step="10" value={volume} onchange={handleChange}>
    </lightning-slider>
  </div>
</template>

初始化自定义属性编辑器时,其 JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中进行更新时,它会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// volumeEditor.js
import { LightningElement, api } from "lwc";

export default class VolumeEditor extends LightningElement {
  _inputVariables = [];

  @api
  get inputVariables() {
    return this._inputVariables;
  }

  // Set a field with the data that was stored from the flow.
  // This data includes the public volume property of the custom volume
  // component.
  set inputVariables(variables) {
    this._inputVariables = variables || [];
  }

  // Get the value of the volume input variable.
  get volume() {
    const param = this.inputVariables.find(({ name }) => name === "volume");
    return param && param.value;
  }

  @api
  validate() {
    const volumeCmp = this.template.querySelector("lightning-slider");
    const validity = [];
    if (this.volume < 0 || this.volume > 100) {
      volumeCmp.setCustomValidity("The slider range is between 0 and 100.");
      validity.push({
        key: "Slider Range",
        errorString: "The slider range is between 0 and 100.",
      });
    } else {
      volumeCmp.setCustomValidity("");
    }
    volumeCmp.reportValidity();
    return validity;
  }

  handleChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name: "volume",
          newValue,
          newValueDataType: "Number",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 和 接口。inputVariablesvalidate

此示例定义了 的 getter 和 setter。初始化自定义属性编辑器时,setter 从 Flow Builder 接收屏幕组件中公共属性的值。在此示例中,我们使用将流元数据存储在字段中的约定,但您可以根据需要命名该字段。inputVariablesinputVariables_inputVariables

中的数据结构包括每个输入变量的名称、值和数据类型。_inputVariables

[
  {
    name: "volume",
    value: "10",
    valueDataType: "Number",
  },
];

该方法获取用于卷 UI 的属性。volumevaluevolume

当管理员在 Flow Builder 的屏幕编辑器 UI 中单击“完成”时,Flow Builder 会评估每个自定义属性编辑器中的函数。如果函数返回 和 数据结构,则 Flow Builder 会显示错误数,并阻止管理员在屏幕编辑器中保存更改。validatekeyerrorString

注意

Flow Builder 仅显示错误数。若要显示错误字符串,请编写代码。此示例使用组件的函数显示自定义错误消息。使用 interface 方法。lightning-slidersetCustomValidity()validate

当管理员在自定义属性编辑器中输入 volume 的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleChangeconfiguration_editor_input_value_changed

这是 的配置文件。volumeEditor

<!--volumeEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>49.0</apiVersion>
  <!--isExposed can be true or false-->
  <isExposed>true</isExposed>
</LightningComponentBundle>

示例:可调用操作的通用 SObject 输入

此示例为使用泛型 sObject 输入参数的可调用操作创建自定义属性编辑器。可调用操作是可以添加到流程中的 Apex 方法。在 Flow Builder 中,管理员使用选择列表字段来设置可调用操作的输入参数:记录变量的对象、记录变量和用于存储输出的对象。当用户运行此示例的流时,可调用操作将存储记录集合中的第一条记录。

此 Apex 类文件定义了可作为可调用操作运行的方法及其输入变量。注释标识可以作为可调用操作运行的方法。注释标识可调用方法使用的变量。selectRecord@InvocableMethod@InvocableVariable

可调用方法在修饰符中注册自定义属性编辑器。除非组织具有自定义命名空间,否则命名空间。如果组织具有自定义命名空间,请使用该命名空间注册自定义属性编辑器。在此示例中,自定义属性编辑器的名称为 。configurationEditorcc-select-record-editor

// SelectRecordAction.cls
public with sharing class SelectRecordAction {
    @InvocableMethod(configurationEditor='c-select-record-editor')
    public static List <Results> selectRecord(List<Requests> requestList) {
        List<SObject> inputCollection = requestList[0].inputCollection;
        //Store the first input record for output
        SObject outputMember = inputCollection[0];
        Results response = new Results();
        response.outputMember = outputMember;
        List<Results> responseWrapper= new List<Results>();
        responseWrapper.add(response);
        return responseWrapper;
    }

public class Requests {
    @InvocableVariable(label='Object for Input' description='Records for Input')
    public List<SObject> inputCollection;
    }

public class Results {
    @InvocableVariable(label='Object for Storing Output' description='Records for Output')
    public SObject outputMember;
    }
}

这些 HTML、CSS、JavaScript 和配置文件定义操作的自定义属性编辑器。

HTML 模板定义 Flow Builder 中自定义属性编辑器的 UI。

<!--selectRecordEditor.html-->
<template>
  <lightning-combobox
    name="inputType"
    label="Object for Record Variable"
    value={inputType}
    placeholder="Select object..."
    options={typeOptions}
    onchange={handleInputTypeChange}
  >
  </lightning-combobox>

  <lightning-combobox
    name="outputType"
    label="Object for Storing Output"
    value={outputType}
    placeholder="Select object..."
    options={typeOptions}
    onchange={handleOutputTypeChange}
  >
  </lightning-combobox>

  <lightning-combobox
    name="inputValue"
    label="Record Variable"
    value={inputValue}
    placeholder="Select record variable..."
    options={valueOptions}
    onchange={handleValueChange}
  >
  </lightning-combobox>

  <div class="slds-p-bottom_medium"></div>
</template>

此示例显示自定义属性编辑器 UI。

初始化自定义属性编辑器后,JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中更改值时,自定义属性编辑器会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// selectRecordEditor.js
import { LightningElement, api } from "lwc";

export default class SelectRecordEditor extends LightningElement {
  @api
  inputVariables;

  @api
  genericTypeMappings;

  @api
  builderContext;

  get inputValue() {
    const param = this.inputVariables.find(({ name }) => name === "inputCollection");
    return param && param.value;
  }

  get inputType() {
    const type = this.genericTypeMappings.find(({ typeName }) => typeName === "T__inputCollection");
    return type && type.typeValue;
  }

  get outputType() {
    const type = this.genericTypeMappings.find(({ typeName }) => typeName === "U__outputMember");
    return type && type.typeValue;
  }

  get typeOptions() {
    return [
      { label: "Account", value: "Account" },
      { label: "Case", value: "Case" },
      { label: "Lead", value: "Lead" },
    ];
  }

  get valueOptions() {
    const variables = this.builderContext.variables;
    return variables.map(({ name }) => ({
      label: name,
      value: name,
    }));
  }

  handleInputTypeChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const typeChangedEvent = new CustomEvent(
        "configuration_editor_generic_type_mapping_changed",
        {
          bubbles: true,
          cancelable: false,
          composed: true,
          detail: {
            typeName: "T__inputCollection",
            typeValue: newValue,
          },
        },
      );
      this.dispatchEvent(typeChangedEvent);
    }
  }

  handleOutputTypeChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const typeChangedEvent = new CustomEvent(
        "configuration_editor_generic_type_mapping_changed",
        {
          bubbles: true,
          cancelable: false,
          composed: true,
          detail: {
            typeName: "U__outputMember",
            typeValue: newValue,
          },
        },
      );
      this.dispatchEvent(typeChangedEvent);
    }
  }

  handleValueChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name: "inputCollection",
          newValue,
          newValueDataType: "reference",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 、 和 接口。inputVariablesbuilderContextgenericTypeMappings

初始化自定义属性编辑器后,从 Flow Builder 接收可调用操作中输入变量的值。inputVariables

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[
  {
    name: "inputType",
    value: "Account",
    valueDataType: "Account",
  },
];

该方法获取每个输入变量的值,以便在自定义属性编辑器中使用。get inputValue()

该接口接收输入变量的值,这些变量是 Flow Builder 中可调用操作中的通用 sObject 数据类型。genericTypeMappings

数据结构包括每个输入的名称和值。必须与使用方法中的注释定义的泛型 sObject 输入的名称匹配,例如 。 在输入名称前面加上,并自动在输出名称前面加上。是通用 sObject 输入的特定值,例如 。typeName@InvocableVariable’T__inputCollection’T__U__typeValueAccount

[
  {
    typeName: "T__inputCollection",
    typeValue: "Account",
  },
];

和方法获取每个输入参数的值,该参数是用于自定义属性编辑器的泛型 sObject 数据类型。get inputType()get outputType()

该方法获取每个对象输入选项的标签和值,以便在自定义属性编辑器中使用。get typeOptions()

该接口提供有关流中元素和资源的数据。builderContext

数据结构包括流中的元素和资源。builderContext

该方法使用变量中的数据作为可调用操作输入参数的自定义属性编辑器上的输入值选项。get valueOptions()

当管理员在自定义属性编辑器中为记录变量的对象输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleInputTypeChangeconfiguration_editor_generic_type_mapping_changed

当管理员在自定义属性编辑器中输入用于存储输出的对象的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleOutputTypeChangeconfiguration_editor_generic_type_mapping_changed

当管理员在自定义属性编辑器中输入“记录变量”的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleValueChangeconfiguration_editor_input_value_changed

下面是 的配置文件。selectRecordEditor

<!--selectRecordEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <!--isExposed can be true or false-->
    <isExposed>true</isExposed>
</LightningComponentBundle>

示例:屏幕组件的通用 SObject 输入

此示例为使用泛型输入值的自定义流屏幕组件创建自定义属性编辑器。管理员使用选择列表字段为记录变量的对象和记录变量设置屏幕组件的输入值。当用户运行此示例的流时,屏幕组件将显示记录集合中的第一条记录。sObject

以下 HTML、JavaScript 和配置文件定义自定义流屏幕组件。displayRecord

<!--displayRecord.html-->
<template>
  <p>Record Name: {inputValue.Name}</p>
</template>

JavaScript 类定义一个公共属性。inputValue

// displayRecord.js
import { LightningElement, api } from "lwc";

export default class DisplayRecord extends LightningElement {
  @api
  inputValue;
}

要在 Flow Builder 中公开公共属性,请在配置文件中定义它。若要将属性定义为泛型数据类型,请定义子标记。子标记扩展泛型数据类型。的属性引用子标记的属性。例如,如果 ,则 .子标记的属性必须位于大括号内。要将属性定义为泛型集合数据类型,请追加 ,例如 。inputValuesObjectpropertyTypesObjecttypeinputValuenamepropertyTypepropertyType name="T"property type="{T}"typepropertysObject[]property type="{T[]}"

该特性确定属性是否可以接收来自流的输入。缺省值为 。若要使属性仅可用于输入或输出,请将该特性设置为 或 。roleinputAndOutputroleinputOnlyoutputOnly

在配置文件中,使用该特性注册自定义属性编辑器。configurationEditor

除非组织具有自定义命名空间,否则请使用命名空间。如果组织具有自定义命名空间,请使用该命名空间。c

<!-- displayRecord.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>50.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <masterLabel>Display Record</masterLabel>
  <targetConfigs>
    <targetConfig targets="lightning__FlowScreen" configurationEditor="c-display-record-editor">
      <propertyType name="T" extends="SObject" label="Input Type" description="Generic sObject data type used for input sObject properties" />
      <property name="inputValue" type={T} label="input value" role="inputOnly" />
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

以下 HTML、JavaScript 和配置文件定义组件的自定义属性编辑器。displayRecord

自定义属性编辑器的 HTML 模板定义了 UI,该 UI 使用组合框基础 Lightning Web 组件。

<!--displayRecordEditor.html-->
<template>
  <lightning-combobox
    name="inputType"
    label="Object for Record Variable"
    value="{inputType}"
    placeholder="Select object..."
    options="{typeOptions}"
    onchange="{handleInputTypeChange}"
  >
  </lightning-combobox>

  <lightning-combobox
    name="inputValue"
    label="Record Variable"
    value="{inputValue}"
    placeholder="Select record variable..."
    options="{valueOptions}"
    onchange="{handleValueChange}"
  >
  </lightning-combobox>
</template>

初始化自定义属性编辑器时,其 JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中进行更新时,它会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

// displayRecordEditor.js
import { LightningElement, api } from 'lwc';

export default class DisplayRecordEditor extends LightningElement {
  @api
  inputVariables;

  @api
  genericTypeMappings;

  @api
  builderContext;

  get inputValue() {
    const param = this.inputVariables.find(({ name }) => name === 'inputValue');
    return param && param.value;
  }

  get inputType() {
    const type = this.genericTypeMappings.find(
      ({ typeName }) => typeName === 'T'
    );
    return type && type.typeValue;
  }

  get typeOptions() {
    return [
      { label: 'Account', value: 'Account' },
      { label: 'Case', value: 'Case' },
      { label: 'Lead', value: 'Lead' },
    ];
  }

  get valueOptions() {
    const variables = this.builderContext.variables;
    return variables.map(({ name }) => ({
      label: name,
      value: name,
    }));
  }

  handleInputTypeChange(event) {
    if (event && event.detail) {
    const newValue = event.detail.value;
    const typeChangedEvent = new CustomEvent(
      'configuration_editor_generic_type_mapping_changed',
      {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          typeName: 'T',
          typeValue: newValue
        },
      }
    );
    this.dispatchEvent(typeChangedEvent);
    }
  }

  handleValueChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent(
        'configuration_editor_input_value_changed',
        {
          bubbles: true,
          cancelable: false,
          composed: true,
          detail: {
            name: 'inputValue',
            newValue,
            newValueDataType: 'reference',
          },
        }
      );
    this.dispatchEvent(valueChangedEvent);
    }
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用 、 和 接口。inputVariablesbuilderContextgenericTypeMappings

初始化自定义属性编辑器后,从 Flow Builder 接收屏幕组件中公共属性的值。inputVariables

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[
  {
    name: "inputType",
    value: "Account",
    valueDataType: "Account",
  },
];

获取要在自定义属性编辑器中使用的属性的值。get inputValue()inputValue

该接口从 Flow Builder 接收输入变量的值,这些变量是屏幕组件中的泛型数据类型。genericTypeMappingssObject

数据结构包括每个输入的名称和值。是泛型输入的名称;例如。是泛型输入的特定值;例如。typeNamesObject'T'typeValuesObjectAccount

[
  {
    typeName: "T",
    typeValue: "Account",
  },
];

获取要在自定义属性编辑器中使用的属性的数据类型。get inputType()inputValue

该方法获取每个对象输入选项的标签和值,以便在自定义属性编辑器中使用。get typeOptions()

该接口提供有关流中元素和资源的数据。builderContext

{
  actionCalls: [],
  apexPluginCalls: [],
  constants: [],
  formulas: [],
  recordCreates: [],
  recordDeletes: [],
  recordLookups: [],
  recordUpdates: [],
  screens: [],
  stages: [],
  textTemplates: [],
  variables: []
}

该方法使用来自 的数据作为屏幕组件输入的自定义属性编辑器上的输入值选项。get valueOptions()variables

当管理员在自定义属性编辑器中为记录变量的对象输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleInputTypeChangeconfiguration_editor_generic_type_mapping_changed

当管理员在自定义属性编辑器中输入“记录变量”的值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleValueChangeconfiguration_editor_input_value_changed

这是 的配置文件。displayRecordEditor

<!--displayRecordEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>50.0</apiVersion>
  <!--isExposed can be true or false-->
  <isExposed>true</isExposed>
</LightningComponentBundle>

示例:可调用操作的 SObject 输入

此示例创建一个自定义属性编辑器组件,该组件以使用 Contact 对象输入参数的可调用操作命名。可调用操作是可以添加到流程中的 Apex 方法。在 Flow Builder 中,管理员使用文本字段来设置可调用操作的联系人输入参数。当用户运行此示例的流时,可调用操作会存储一个新联系人。createContactActionEditor

此 Apex 类文件定义了可作为可调用操作运行的方法及其输入变量。注释标识可以作为可调用操作运行的方法。注释标识可调用方法使用的变量。createContact@InvocableMethod@InvocableVariable

可调用方法在修饰符中注册自定义属性编辑器组件。除非组织具有自定义命名空间,否则组件命名空间。如果组织具有自定义命名空间,请使用该命名空间注册自定义属性编辑器组件。在此示例中,组件的名称为 。configurationEditorcc-create-contact-action-editor

//CreateContactAction.cls
global class CreateContactAction {
    global class CreateContactRequest {

        @InvocableVariable
        global Contact contact;
    }

    global class CreateContactResult {
        @InvocableVariable
        global Boolean isSuccess;

        @InvocableVariable
        global String errorMessage;

        @InvocableVariable
        global String contactId;
   }

    @InvocableMethod(label='Create Contact' configurationEditor='c-create-contact-action-editor')
    global static List<CreateContactResult> createContact(List<CreateContactRequest> requests) {
        List<CreateContactResult> results = new List<CreateContactResult>();
            for(CreateContactRequest request : requests){
        results.add(insertContact(request));
        }
        return results;
    }

    public static CreateContactResult insertContact(CreateContactRequest request) {
        List<Contact> contactList = new List<Contact>();
        contactList.add(request.contact);

        Database.SaveResult[] srList = Database.insert(contactList, true);

        CreateContactResult contactResult = new CreateContactResult();
            for(Database.SaveResult sr: srList) {
                if (sr.isSuccess()) {
                    contactResult.isSuccess = sr.isSuccess();
                    contactResult.contactId = sr.getId();
                }
                else {
                    for(Database.Error err : sr.getErrors()) {
                        contactResult.errorMessage = err.getStatusCode() + ': ' + err.getMessage();
                    }
                }
            }

    return contactResult;
    }
}

下面是 的配置文件。CreateContactAction

<!--CreateContactAction.cls-meta.xml-->

<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="urn:metadata.tooling.soap.sforce.com" fqn="CreateContactAction">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>

这些 HTML、CSS、JavaScript 和配置文件定义操作的自定义属性编辑器组件。createContactActionEditor

组件的 HTML 模板定义了 Flow Builder 中自定义属性编辑器的 UI。

<!--createContactActionEditor.html-->

<template>
  <div class="slds-m-top_small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">
      Contact Primary Information
    </h2>

    <lightning-input
      label="First Name"
      value={defaultContact.FirstName}
      onchange={handleFirstNameChange}
    >
    </lightning-input>

    <lightning-input
      label="Last Name"
      value={defaultContact.LastName}
      onchange={handleLastNameChange}
    >
    </lightning-input>
  </div>

  <div class="slds-m-top_small">
    <h2 class="slds-text-heading_medium slds-p-around_xx-small lgc-bg-inverse">Contact Source</h2>

    <lightning-input
      label="European Country Code"
      value={defaultContact.European_Country_Code__c}
      onchange={handleCountryCodeChange}
    >
    </lightning-input>
  </div>
</template>

此示例显示自定义属性编辑器 UI。

初始化自定义属性编辑器组件时,其 JavaScript 类会从 Flow Builder 接收流元数据的副本。当管理员在自定义属性编辑器中更改值时,自定义属性编辑器组件会调度一个事件以将更改传播回 Flow Builder。

注意

使用属性从流中捕获数据。使用事件在运行时报告对流的更改。@api

//createContactActionEditor.js

import { LightningElement, api } from "lwc";

export default class CreateContactActionEditor extends LightningElement {
  @api
  inputVariables;

  defaultContact = {
    attributes: {
      type: "Contact",
    },
    European_Country_Code__c: "FRA",
  };

  get contact() {
    const param = this.inputVariables.find(({ name }) => name === "contact");
    return param && param.value;
  }

  handleFirstNameChange(event) {
    this.defaultContact["FirstName"] = event.detail.value;
    this.handleContact();
  }

  handleLastNameChange(event) {
    this.defaultContact["LastName"] = event.detail.value;
    this.handleContact();
  }

  handleCountryCodeChange(event) {
    this.defaultContact["European_Country_Code__c"] = event.detail.value;
    this.handleContact();
  }

  handleContact() {
    const newValue = JSON.stringify(this.defaultContact);
    const valueChangedEvent = new CustomEvent("configuration_editor_input_value_changed", {
      bubbles: true,
      cancelable: false,
      composed: true,
      detail: {
        name: "contact",
        newValue,
        newValueDataType: "SObject",
      },
    });
    this.dispatchEvent(valueChangedEvent);
  }
}

Flow Builder 具有用于与自定义属性编辑器进行通信的 JavaScript 接口。此 JavaScript 类使用该接口。inputVariables

初始化自定义属性编辑器后,从 Flow Builder 接收可调用操作中输入变量的值。缺省值为 type 和 设置。当您对 sObject 数据类型的输入使用文本值时,请指定该值,例如 。inputVariablesEuropean_Country_Code__ctypeContact

数据结构包括每个输入变量的名称、值和数据类型。inputVariables

[{
    name: 'contact',
    value: '{
        "attributes": {
            "type": "Contact"
        },
        "FirstName" : "",
        "LastName": "",
        "European_Country_Code__c" : "FRA"
    }',
    valueDataType: 'SObject'
}]

该方法获取输入变量的值,以便在自定义属性编辑器中使用。get contact()

当管理员在自定义属性编辑器中输入输入值时,该方法会将事件调度到 Flow Builder。Flow Builder 接收事件并更新流中的值。handleContactconfiguration_editor_input_value_changed

下面是 的配置文件。createContactActionEditor

<!---createContactActionEditor.js-meta.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <!--isExposed can be true or false-->
    <isExposed>true</isExposed>
</LightningComponentBundle>

自定义属性编辑器 JavaScript 接口

自定义属性编辑器使用这些 JavaScript 函数与 Flow Builder 进行通信。

输入变量

该接口提供有关 FlowScreenField 元数据的数据。inputVariables

_inputVariables = [];

@api
get inputVariables() {
    return this._inputVariables;
}

// Set a field with the data that was stored from the flow.
set inputVariables(variables) {
    this._inputVariables = variables || [];
}

中的数据结构包括每个输入变量的名称、值和数据类型。_inputVariables

[{
    name: 'volume',
    value: '10',
    valueDataType: 'Number'
}]

有关流元数据的更多信息,请参阅流元数据 API。

builder上下文

该接口提供有关流中元素和资源的数据。例如,和数据结构包括输入变量的名称和类型。在 Flow Builder 中,管理员可以将有关其他元素和资源的数据用作屏幕组件输入属性的自定义属性编辑器的输入。builderContextscreensactionCalls

从界面传递到自定义属性编辑器的数据结构包括流中的元素和资源。builderContext

{
    actionCalls: [],
    apexPluginCalls: [],
    constants: [],
    formulas: [],
    recordCreates: [],
    recordDeletes: [],
    recordLookups: [],
    recordUpdates: [],
    screens: [],
    stages: [],
    textTemplates: [],
    variables: []
}

有关流元数据的更多信息,请参阅流元数据 API。

在以下示例中,开发人员创建自定义流屏幕组件及其自定义属性编辑器。在 Flow Builder 中,管理员使用组合框设置电子邮件的发件人姓名。当用户运行流程时,流程屏幕会显示电子邮件的选定名称。

以下 HTML、JavaScript 和配置文件定义自定义流屏幕组件。

<!--htmlEmail.html-->
<template>
  <p>Selected sender's name is: {senderName}</p>
</template>

此 JavaScript 文件定义了一个公共属性。senderName

// htmlEmail.js

import { LightningElement, api } from "lwc";

export default class HTMLEmail extends LightningElement {
  @api senderName;
}

此配置文件注册自定义属性编辑器。

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>49.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__FlowScreen</target>
    </targets>
    <masterLabel>HTMLEmail</masterLabel>
    <targetConfigs>
        <targetConfig targets="lightning__FlowScreen" configurationEditor="c-html-email-editor">
            <property name="senderName" type="String" role="inputOnly" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

以下 HTML、JavaScript 和配置文件定义屏幕组件的自定义属性编辑器。

此 HTML 文件定义 Flow Builder 中自定义属性编辑器的 UI。UI 显示一个组合框基础 Lightning Web 组件。

<!--htmlEmailEditor.html-->
<template>
  <div class="slds-p-around_xx-small">
    <lightning-combobox
      name="senderName"
      label="Sender Display Name"
      value={senderName}
      placeholder="Select Sender"
      options={options}
      onchange={handleChange}
    >
    </lightning-combobox>

    <p class="slds-p-top_xx-small">Selected sender's name is: {senderName}</p>
  </div>
</template>

初始化自定义属性编辑器时,JavaScript 类会从 Flow Builder 接收流元数据的副本。如果管理员在自定义属性编辑器中进行更新,则会调度一个事件以将更改传播回 Flow Builder。

// htmlEmailEditor.js
import { LightningElement, api } from "lwc";
export default class HtmlEmailEditor extends LightningElement {
  @api
  inputVariables;

  @api
  builderContext;

  get senderName() {
    const param = this.inputVariables.find(({ name }) => name === "senderName");
    return param && param.value;
  }

  get options() {
    const variables = this.builderContext.variables;
    return variables.map(({ name, value }) => ({
      label: name,
      value: value.stringValue,
    }));
  }

  handleChange(event) {
    if (event && event.detail) {
      const newValue = event.detail.value;
      const valueChangedEvent = new CustomEvent("Configuration_editor_input_value_changed", {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name: "senderName",
          newValue,
          newValueDataType: "String",
        },
      });
      this.dispatchEvent(valueChangedEvent);
    }
  }
}

该方法返回有关使用接口存储的输入变量的信息。该方法返回使用接口方法存储的合并字段列表。自定义属性编辑器将合并字段显示为屏幕组件输入属性的输入值。senderNamesenderNameinputVariablesoptionsbuilderContext

元素信息

该接口提供有关调用自定义属性编辑器的自定义流屏幕组件或自定义操作的数据。使用此接口可以消除屏幕组件或操作的不同实例的歧义。elementInfo

此示例将流元数据存储在 中,但您可以随意命名该字段。_elementInfo

_elementInfo = {};
@api
get elementInfo() {
    return this._elementInfo;
}

// Set a local variable with the data that was stored from flow.
set elementInfo(info) {
    this._elementInfo = info || {};
}

中的数据结构包括流元数据中流元素的 API 名称和类型。_elementInfo

{
    apiName: 'slider',
    type: 'Screen'
}

type 的有效值为:

  • Screen– 屏幕元素
  • Action– 动作元素

驗證

使用该界面在自定义属性编辑器中执行自定义验证。当流程管理员在 Flow Builder 的屏幕编辑器中单击“完成”时,Flow Builder 会评估每个自定义属性编辑器中的函数。如果函数返回 和 数据结构,则屏幕编辑器会显示错误数。validatevalidatekeyerrorString

注意

Flow Builder 仅显示错误数。编写代码以在自定义属性编辑器中显示错误字符串。

此示例将数据存储在字段中,但您可以使用任何字段名称。为了在自定义属性编辑器中显示错误字符串,我们用于查询、设置和报告错误字符串。validitysliderCmp

@api
validate() {
    const sliderCmp = this.template.querySelector('lightning-slider');
    const validity = [];
    if (this.volume < 0 || this.volume > 100) {
        sliderCmp.setCustomValidity('The slider range is between 0 and     100.');
        validity.push({
            key: 'Slider Range',
            errorString: 'The slider range is between 0 and 100.',
        });
    } else {
        sliderCmp.setCustomValidity('');
    }
    sliderCmp.reportValidity();
    return validity;
}

genericTypeMappings

数据结构包括每个输入的名称和值。是泛型输入的名称;例如。是泛型输入的特定值;例如。genericTypeMappingstypeNamesObject‘T__param1’typeValuesObjectAccount

[{
    typeName: 'T__param1',
    typeValue: 'Account'
}]

事件类型

要向 Flow Builder 报告输入值更改,请从自定义属性编辑器的函数中调度事件。设置为 和 true。handleChangebubblescomposed

事件类型的有效值为:

  • configuration_editor_input_value_changed– 一种事件类型,在输入值更改时调度。
  • configuration_editor_input_value_deleted– 删除输入值时调度的事件类型。
  • configuration_editor_generic_type_mapping_changed– 一种事件类型,在通用输入值更改时调度。sObject

这些属性定义用于报告更改的输入。detail

  • name– 屏幕组件的 JavaScript 类中的输入变量。
  • newValue– 输入的新值。
  • newValueDataType– 输入的新数据类型。
  • typeName– 屏幕组件的 JavaScript 类或可调用方法的 Apex 类中的泛型输入。要在屏幕组件的自定义属性编辑器中引用 ,请引用子标记的属性。该值必须位于大括号内,例如。要将属性定义为泛型集合数据类型,请追加 ,例如 。要在自定义属性编辑器中引用可调用操作的 ,请在输入名称和输出名称前面加上 ,例如 。sObjecttypeNamepropertyTypenameproperty type="{T}"sObject[]property type="{T[]}"typeNameT__U__T__param1
  • typeValue– 通用输入或输出的特定值。sObject

例如,当管理员在自定义属性编辑器中输入值 for 时,它会调度一个事件。Flow Builder 接收事件并更新流中的值。volume

handleChange(event) {
    if (event && event.detail) {
        const newValue = event.detail.value;
        const valueChangedEvent = new CustomEvent(
            'configuration_editor_input_value_changed', {
            bubbles: true,
            cancelable: false,
            composed: true,
            detail: {
                name: 'volume',
                newValue,
                newValueDataType: 'Number'
            }
            }
        );
        this.dispatchEvent(valueChangedEvent);
    }
}

流中支持的数据类型

并非所有自定义 Lightning Web 组件数据类型在流程中都受支持。您只能在流程和自定义 Lightning Web 组件之间映射这些类型及其关联的集合类型。

流数据类型Lightning Web 组件数据类型有效值
Apex(流量标签:Apex-Defined)自定义 Apex 类定义字段的 Apex 类。Apex 类中支持的数据类型包括 Boolean、Integer、Long、Decimal、Double、Date、DateTime 和 String。每种数据类型都支持单个值和列表。@AuraEnabled
布尔布尔真实值:true1等效表达式False 值:false0等效表达式
货币整数数值或等效表达式
日期日期"YYYY-MM-DD"或等效表达式
DateTime(流标签:日期/时间)日期时间"YYYY-MM-DDThh:mm:ssZ"或等效表达式
数值或等效表达式
Multipicklist(流标签:Multi-Select Picklist)字符串字符串值或使用分号分隔格式的等效表达式:“Blue;绿;黄色”
选择列表字符串字符串值或等效表达式
sObject(流标签:记录)特定对象的 API 名称,例如 Account 或 Case键值对或等效表达式的映射。流记录值仅映射到类型为特定对象的属性。例如,客户记录变量只能映射到类型为 Account 的属性。流不支持 Object 数据类型。
字符串(流标签:文本)字符串字符串值或等效表达式

Flow 

Flow Builder 允许管理员使用流自动执行业务流程。了解如何开发和配置 Lightning Web 组件,以用作 Flow Builder 中操作和屏幕组件的流屏幕组件和自定义 UI。

创建流屏组件

正如管理员在 Lightning App Builder 中配置记录页面的用户体验一样,他们使用流屏幕组件为流用户执行相同的操作。每个屏幕都由一个或多个屏幕组件组成。

为流屏幕配置组件

要在流程屏幕中使用自定义 Lightning Web 组件,请将一些元数据添加到组件的配置文件中。

componentName.js-meta.xml 文件定义组件的元数据值,包括用于流屏幕的组件的设计配置。

  • 若要使组件在流屏幕中可用,请添加目标。lightning__FlowScreen
  • 若要向组件添加输入字段,请添加属性。targetConfig
  • 若要将属性限制为 或 ,请使用该特性。例如,如果某个属性限制为 ,则用户无法从 Lightning 记录页面设置其值。如果未指定属性,则默认值允许输入和输出。inputOnlyoutputOnlyroleoutputOnlyrole

请参阅 XML 配置文件元素的完整列表。

此示例组件有 5 个流屏幕输入字段。该属性设置为 。startDateinputOnly

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>47.0</apiVersion>
  <isExposed>true</isExposed>
  <masterLabel>Best Component Ever</masterLabel>
  <description>This is a demo component.</description>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__FlowScreen">
      <property name="startDate" label="Start Date" type="Date" role="inputOnly" />
      <property name="account" label="Account Chosen" type="@salesforce/schema/Account" />
      <property name="annualRevenue" label="Annual Revenue" type="Integer" role="outputOnly" />
      <property name="name" label="Account Name" type="String" />
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

验证自定义流屏幕组件的用户输入

向自定义屏幕组件添加验证。

要使用 Flow 的验证功能,请在组件的 JavaScript 文件中创建一个调用的函数。validate()

// sampleValidate.js
@api
validate() {
  if(/* true conditions */) {
    return { isValid: true };
    }
  else {
    // If the component is invalid, return the isValid parameter
    // as false and return an error message.
    return {
      isValid: false,
      errorMessage: '/*A message that explains what went wrong.*/'
    };
  }
}

注意

箭头函数表达式不适用于 的组件中的验证。targetlightning__FlowScreen

在自定义 Lightning Web 组件中嵌入流程

嵌入来自任何 Lightning Web 组件的屏幕流,以自定义完成行为、设置自定义样式或从 Lightning Web 组件启动流程。

在自定义 Lightning Web 组件中创建和启动流程

创建并启动从任何 Lightning Web 组件到您的屏幕流。

lightning-flow表示 Lightning 运行时中的流程面试。若要在组件中创建流,请将组件的属性设置为要使用的流的 API 名称。要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。lightning-flowflow-api-name

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

此示例创建并启动“调查客户”流。

<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name="Survey_customers"> </lightning-flow>
</template>

您可以通过将属性设置为输入值数组来提供面试的初始输入。flow-input-variables

此示例通过传入流程的初始值来创建和启动面试。它使用事件处理程序处理面试中的更改。onstatuschange

<!-- myComponent.html -->
<template>
  <lightning-flow
    flow-api-name={flowName}
    flow-input-variables={inputVariables}
    onstatuschange={handleStatusChange}>
  </lightning-flow>
</template>
// myComponent.js
import { LightningElement } from "lwc";

export default class MyComponent extends LightningElement {
  opportunityId;
  accountId;
  customerLocation;

  get flowName() {
    if (this.customerLocation === "USA") {
      flowname = "Survey_USA";
    } else {
      flowname = "Survey_General";
    }
  }

  get inputVariables() {
    return [
      {
        // Match with the input variable name declared in the flow.
        name: "OpportunityID",
        type: "String",
        // Initial value to send to the flow input.
        value: this.opportunityId,
      },
      {
        // Match with the input variable name declared in the flow.
        name: "AccountID",
        type: "String",
        // Initial value to send to the flow input.
        value: this.accountId,
      },
    ];
  }

  handleStatusChange(event) {
    if (event.detail.status === "FINISHED") {
      // set behavior after a finished flow interview.
    }
  }
}

使用注意事项

该组件仅支持该属性的活动流。lightning-flowflow-api-name

该事件返回这些参数。onstatuschange

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

参数类型描述
活动阶段对象[]流中 $Flow.ActiveStages 变量的当前值。在 API 版本 42.0 及更高版本中可用。
当前阶段对象流中 $Flow.CurrentStage 变量的当前值。在 API 版本 42.0 及更高版本中可用。
flowTitle (流标题)字符串流的标签。
帮助文本字符串当前屏幕的帮助文本。在 API 版本 42.0 及更高版本中可用。
GUID字符串面试的 GUID。在 API 版本 42.0 及更高版本中可用。
输出变量对象[]流输出变量的当前值。
地位字符串面试的状态。流程面试的有效状态为:STARTED:面试成功开始。PAUSED:采访成功暂停。FINISHED:屏幕完成的流程面试。FINISHED_SCREEN:没有屏幕的流的面试已完成,组件显示默认屏幕,其中包含以下消息:您的流已完成。ERROR:出了点问题,面试失败了。

自定义流的完成行为

每个流组件都包括导航按钮“后退”、“下一步”、“暂停”和“完成”,这些按钮在流中导航。默认情况下,当流程完成时,组件会重新加载新面试的第一个屏幕。若要自定义流程完成时发生的情况,请在状态为 FINISHED 时为操作添加事件处理程序。onstatuschange

设置流输入变量

在自定义组件中嵌入流时,通过初始化流的变量为流提供更多上下文。若要在组件中创建流,请将组件的属性设置为要使用的流的 API 名称。lightning-flowlightning-flowflow-api-name

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

为流创建输入变量

在组件的 Javascript 文件中,创建一个映射列表,并将该列表传递给属性。flow-input-variables

注意

您只能在面试开始时设置变量,并且您设置的变量必须允许输入访问。如果引用的变量不允许输入访问,则会忽略设置该变量的尝试。

对于您设置的每个变量,请提供变量的名称、类型和值。对于 type (类型),请使用 API 名称作为流数据类型。例如,对于记录变量,请使用 SObject,对于文本变量,请使用 String。

{
  name : "varName",
  type : "flowDataType",
  value : valueToSet
},
{
  name : "varName",
  type : "flowDataType",
  value : [ value1, value2 ]
}, ...

JavaScript 文件中的此方法返回一个数字变量、一个日期集合变量和几个记录变量的值数组。Flow Builder 中的 Record 数据类型与此处的 SObject 相对应。

// myComponent.js
get inputVariables() {
  return [
    { name: 'numVar', type: 'Number', value: 30 },
    { name: 'dateColl', type: 'String', value: [ '2016-10-27', '2017-08-01' ] },
    // Sets values for fields in the account record (sObject) variable.
    // Id uses the value of the accountId property. Rating uses a string.
    { name: 'account', type: 'SObject', value: {
      'Id': this.accountId,
      'Rating': 'Warm'
    }},
    // Set the contact record (sObject) variable to the value of the contact property.
    // We're assuming the property contains the entire sObject for a contact record.
    { name: 'contact', type: 'SObject', value: this.contact }
  ]
}

示例:将帐户数据传递到流

此示例组件通过 Apex 控制器获取帐户。Apex 控制器通过 JavaScript 文件中的线路将数据传递到流的记录变量。

<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name="myFlow" flow-input-variables={inputVariables}> </lightning-flow>
</template>
// AccountController.apex
public with sharing class AccountController {
    @AuraEnabled(cacheable=true)
    public static Account getAccount() {
        return [SELECT Id, Name, LastModifiedDate, FROM Account LIMIT 1];
    }
}
// myComponent.js
import { LightningElement, track, wire } from "lwc";
import getAccount from "@salesforce/apex/AccountController.getAccount";

export default class MyComponent extends LightningElement {
  @track
  inputVariables = [];

  @wire(getAccount)
  getAccountFromApex({ error, data }) {
    if (error) {
      console.log("Failed to get account data.");
    } else if (data) {
      this.inputVariables = [
        {
          name: "account",
          type: "SOjbect",
          value: data,
        },
      ];
    }
  }
}

从流输出变量中获取值

在组件中嵌入流时,可以显示或引用流的变量值。lightning-flow

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

使用 onstatuschange 事件处理程序

若要从流的输出变量中获取值,请使用事件处理程序。输出变量以数组形式返回。该变量必须允许输出访问。如果引用的变量不允许输出访问,则会忽略获取该变量的尝试。onstatuschange

示例:显示流的输出变量

此示例获取 和 的流输出变量,并将其显示在模板中。accountNamenumberOfEmployees

<!-- myComponent.html -->
<template>
  <p>{accountName}</p>
  <p>{numberOfEmployees}</p>
  <lightning-flow flow-api-name="myFlow" onstatuschange={handleStatusChange}> </lightning-flow>
</template>
// myComponent.js
import { LightningElement, track, wire } from "lwc";

export default class MyComponent extends LightningElement {
  accountName;
  numberOfEmployees;

  handleStatusChange(event) {
    if (event.detail.status === "FINISHED") {
      const outputVariables = event.detail.outputVariables;
      for (let i = 0; i < outputVariables.length; i++) {
        const outputVar = outputVariables[i];
        if (outputVar.name == "accountName") {
          this.accountName = outputVar.value;
        } else {
          this.numberOfEmployees = outputVar.value;
        }
      }
    }
  }
}

控制流程面试完成后发生的情况

通过将流嵌入到自定义组件中,可以确定流完成时发生的情况。lightning-flow

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

使用 lightning-flow 嵌入流

默认情况下,当流程用户单击“完成”时,将开始新的面试,并且用户将再次看到流程的第一个屏幕。通过将流嵌入到自定义组件中,可以使用事件处理程序来调整流完成时发生的情况。lightning-flowonstatuschange

  • 若要重定向到其他页面,请使用导航服务。
  • 要控制自动启动的流程完成时发生的情况,请检查FINISHED_SCREEN状态。
<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name="myFlow" onstatuschange={handleStatusChange}> </lightning-flow>
</template>
// myComponent.js
handleStatusChange(event) {
    if(event.detail.status === 'FINISHED') {
        // Redirect to another page in Salesforce., or
        // Redirect to a page outside of Salesforce., or
        // Show a toast, or something else
    }
}

示例:在流程完成后导航到记录

此示例使用该方法将用户重定向到在流中创建的案例。 lightning/navigationNavigationMixin.Navigate

// myComponent.js
import { LightningElement } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class MyComponent extends NavigationMixin(LightningElement) {
  navigateToRecord(recordId) {
    this[NavigationMixin.Navigate]({
      type: "standard__recordPage",
      attributes: {
        recordId,
        actionName: "view",
      },
    });
  }

  handleStatusChange(event) {
    if (event.detail.status === "FINISHED") {
      const outputVariables = event.detail.outputVariables;
      for (let i = 0; i < outputVariables.length; i++) {
        const outputVar = outputVariables[i];
        if (outputVar.name === "redirect") {
          this.navigateToRecord(outputVar.value);
        }
      }
    }
  }
}

恢复流程面试

您可以通过将组件嵌入到自定义 LWC 组件中来自定义用户恢复访谈的方式和位置。lightning-flow

要使用此组件,请先使用 Salesforce Flow Builder 构建流程。该组件包括导航按钮“后退”、“下一步”、“暂停”和“完成”。

注意

如果您的流程具有自定义 Lightning Web 组件或 Aura 组件,则无法在使用 Lightning Web Runtime 的 Experience Cloud 站点上使用。lightning-flow

处理暂停的面试

默认情况下,用户可以从其主页上的“暂停的访谈”组件中恢复他们暂停的访谈。若要自定义用户恢复访谈的方式和位置,请将组件嵌入到自定义 LWC 组件中,并将访谈 ID 传递到属性中。lightning-flowflow-interview-id

此示例说明如何恢复面试或开始新的面试。当用户单击联系人记录中的“调查客户”时,该组件将执行其中一项操作。lightning-flow

  • 如果用户对“调查客户”流有任何暂停的访谈,则该组件将恢复第一个访谈。lightning-flow
  • 如果用户对调查客户流没有任何暂停的访谈,则该组件将启动一个新访谈。lightning-flow
<!-- myComponent.html -->
<template>
  <lightning-flow flow-api-name={flowName} flow-interview-id={pausedInterviewId}>
  </lightning-flow>
</template>

示例:使用 Apex 恢复或开始新的面试

此 Apex 控制器通过执行 SOQL 查询来获取暂停访谈的列表。如果没有暂停的访谈,则查询将返回 null 值,然后组件将启动新的访谈。如果查询返回至少一个采访,则该组件将恢复该列表中的第一个采访。

// InterviewsController.apex
public class InterviewsController {
    @AuraEnabled(cacheable=true)
    public static String getPausedId() {
        // Get the ID of the running user.
        String currentUser = UserInfo.getUserId();
        // Find all of that user’s paused interviews for the Survey customers flow.
        List<FlowInterview> interviews =
             [ SELECT Id FROM FlowInterview WHERE CreatedById = :currentUser AND
                 InterviewLabel LIKE '%Survey customers%'];
        if (interviews == null || interviews.isEmpty()) {
            return null; // early out
        }
        // Return the ID for the first interview in the list.
        return interviews.get(0).Id;
    }
}

如果 Apex 控制器返回采访 ID,则传递到该属性。如果 Apex 控制器返回空访谈 ID,则组件通过将流名称传递给属性来启动新的访谈。pausedInterviewIdflow-interview-idflow-api-name

// myComponent.js
import { LightningElement, wire } from "lwc";
import getPausedId from "@salesforce/apex/InterviewsController.getPausedId";

export default class MyComponent extends LightningElement {
  flowName;
  pausedInterviewId;

  @wire(getPausedId)
  getPausedInterviewId({ error, data }) {
    if (error) {
      // start a new interview since no interview id was returned.
      this.flowName = "Survey_customers";
    } else if (data) {
      // resume the flow with the returned interview id.
      this.pausedInterviewId = data;
    }
  }
}

流屏组件的运行时注意事项

为流程配置组件时,请查看这些注意事项,以定义属性和流程运行时行为。

  • 处理 null 默认输入值。如果流程管理员未为自定义屏幕组件设置默认输入值,则流程生成器会在组件运行时传递一个值。若要在运行时设置默认值,请添加处理程序。nullnull
  • 通知运行时属性更改。Lightning Web 组件使用事件来报告从组件到流程的更改。为了通知流运行时属性更改,组件会触发事件。例如,在满足条件时使用条件可见性呈现屏幕组件时,或者将输出属性的值映射到流变量时,请使用此事件。有关代码示例,请参见。FlowAttributeChangeEventlightning-flow-support

设置屏幕流组件的反应性

屏幕流反应性意味着使屏幕流组件更改影响另一个同一屏幕组件。

在 Flow 构建器中添加和配置自定义 Lightning Web 组件之前,请创建自定义 LWC。

如果您计划构建反应式屏幕组件或使用支持的组件,则需要了解每个组件的注意事项。反应性包括:

  • 确定哪个屏幕组件是源,哪个组件是反应式组件。
  • 了解每组组件的不同交互。

示例:标准流量组件到标准流量组件

使用标准 Flow 组件是实现反应性的最简单方法。

使用标准 Flow 组件,您可以添加组件,为每个组件提供 API 名称和标签(如果需要),标识源和反应式组件,然后保存并运行流。

要使 Name 组件的 First Name 字段响应并显示来自 Text 组件的所有文本输入,请执行以下操作:

  1. 在流程中,添加组件和组件,并为每个组件提供标签。TextName
  2. 在组件的 First Name’s source 字段中,选择组件作为源。源可以是同一类型的任何组件,在本例中,Text 组件的类型和 Name 组件的 First Name 字段的类型为 String。NameText
  3. 保存并运行 Flow,然后在组件的输入中键入 .键入每个字符后,“名字”字段会立即更新。TextThis is Reactivity

示例:标准流组件到自定义 Lightning Web 组件

让您的自定义组件对标准 Flow 组件中的更改做出反应。

要创建自定义组件并将其添加到 Flow Builder 中,请执行以下操作:colorName

  1. 添加“文本”组件和“自定义”组件,并为每个组件提供标签。colorName
  2. 在 colorName 的属性中,选择组件作为“颜色名称”字段的源。Text

对文本输入所做的任何更改都会自动反映在自定义 Lightning Web 组件 .例如,在文本输入中输入洋红色会导致 LWC 显示具有相同颜色 magenta 样式的颜色名称。colorName

<!-- colorName.html -->
<template>
  <p>
    Color name has the same color :
    <span style={colorStyle}>{color}</span>
  </p>
</template>
// colorName.js
import { LightningElement, api } from "lwc";

export default class colorName extends LightningElement {
  @api color;

  get colorStyle() {
    return "color:" + this.color;
  }
}
// colorName.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
 <apiVersion>52.0</apiVersion>
 <isExposed>true</isExposed>
 <masterLabel>Color Name</masterLabel>
 <description>Reactive Color Name</description>
 <targets>
     <target>lightning__FlowScreen</target>
 </targets>
<targetConfigs>
      <targetConfig targets="lightning__FlowScreen">
          <property name="color" label="Name of Color" type="String" />
      </targetConfig>
</targetConfigs>
</LightningComponentBundle>

示例:将 Lightning Web 组件自定义为标准流组件

使自定义文本组件对标准 Flow 组件做出反应。

  1. 使用示例中引用的装饰器创建公共字段。@apicustomText.js
  2. 在文件中添加具有示例中引用的适当类型的目标配置。.js-meta.xmlcustomText.js-meta.xml
  3. 添加附加了事件处理程序的输入字段以存储用户输入。
  4. 在事件处理程序中,触发组件中定义的事件。事件名称必须与公共字段的名称匹配,才能使反应性起作用。由于 Flow Runtime 的性质,setter 方法在触发事件后调用,并在反应性导致对公共字段的更改时调用该方法。FlowAttributeChangeflow-supportFlowAttributeChangeFlowAttributeChange
  5. 创建自定义组件后,将该组件添加到带有标签的 Flow 构建器中。
  6. 若要使 Text 组件对自定义组件做出反应,请将 Text 组件上的默认值源配置为自定义组件的公共属性。
<!-- customText.html -->
<template>
  <lightning-input type="text" label="This is custom text" onchange={handleInputChange}>
  </lightning-input>
</template>
// customText.js
import LightningElement, api, track } from 'lwc';
import { FlowAttributeChangeEvent } from 'lightning/flowSupport';

export default class customText extends LightningElement {
   @track _input;

   @api
   set customTextValue(input) {
       if (input) {
           this._input = input;
       }
   };
   get customTextValue() {
       return this._input;
   }

   handleInputChange(event) {
       const attributeChangeEvent = new FlowAttributeChangeEvent('customTextValue', event.target.value);
       this.dispatchEvent(attributeChangeEvent);
   }
}
// customText.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
 <apiVersion>52.0</apiVersion>
 <isExposed>true</isExposed>
 <masterLabel>Custom Text</masterLabel>
 <description>Custom Text Example</description>
 <targets>
     <target>lightning__FlowScreen</target>
 </targets>
<targetConfigs>
      <targetConfig targets="lightning__FlowScreen">
          <property name="customTextValue" label="Custom Text Value" type="String" />
      </targetConfig>
</targetConfigs>
</LightningComponentBundle>

示例:自定义 Lightning Web 组件到自定义 Lightning Web 组件

使自定义 Lightning Web 组件对另一个自定义组件做出反应。

此示例假定组件和组件都已添加到 Flow Builder 中。该组件用于控制组件。customTextcolorNamecustomTextcolorName

  1. 添加组件和组件,并为每个组件提供标签。customTextcolorName
  2. 在组件的 Name of Color 字段中,选择组件作为源。colorNamecustomText

对组件所做的任何更改都会自动反映在 中的颜色公共字段中。例如,输入输入会导致显示具有相同颜色样式的颜色名称,即洋红色。customTextcolorNamemagentacustomTextcolorName

屏幕流中反应性的最佳做法

确保您的 Lightning Web 组件在 Flow 运行时引擎中很好地集成,并按预期工作以实现 Screen Flow 反应性。

状态管理和反应性

这些部分介绍了在屏幕流中具有反应性的状态管理,包括:

  • LWC 状态管理与 Aura 有何不同
  • 状态管理在新的 LWC Flow Runtime 中的工作原理
  • 为屏幕流构建 LWC 时要遵循的状态管理和事件最佳实践

Aura 与 LWC 中的状态管理

Aura 组件和 LWC 的状态管理遵循不同的范式。在 Aura 组件中,由它们所属的组件(包括外部组件)查看和修改。LWC 被设计为在内部和外部状态之间具有明确的分离。声明的变量只能由 LWC 的父级修改。没有注释的变量和带有注释的变量被视为内部状态,可以在定义它们的 LWC 中更改。<aura:attributes />@api@api@track

屏幕流中的 LWC 状态管理

Flow 运行时遵循 LWC 状态管理设计原则。当它渲染的 LWC 组件不修改其自身属性时,它效果最佳。相反,组件通过触发请求更改,这是必不可少的,原因有几个。@apiFlowAttributeChangeEvent

  • 允许其父级控制其属性的组件更容易重用,因为它们允许应用程序控制状态,而不是组件自己的内部业务逻辑。@api
  • 通过触发属性更改事件,Flow 运行时可以准确了解组件状态。Flow 运行时可以控制组件间的交互,例如条件字段可见性,这是反应性的一部分。

使用 LWC linter 规则是确保组件不会修改属性的绝佳方法。在开发环境中设置使用 LWC 的 linter 规则的 linter,特别是确保强制执行该设置。@api

流导航时的状态管理

为了在 Flow Runtime 版本之间保持一致的行为,当用户单击“下一步”或“完成”按钮时,Flow Runtime 会通过提取每个自定义 LWC 组件的当前属性状态来收集值,然后再移动到下一个屏幕或完成流程。此机制可确保不符合规定设计模式的组件在最新的 Flow Runtime 版本中继续工作。强烈建议避免依赖此行为。@api

下面是一个简单的文本输入组件示例,该组件演示了触发而不是更新 LWC 的属性:FlowAttributeChangeEvent@api

@api textValue;

handleTextInputChange(event) {
  const event = new FlowAttributeChangeEvent('textValue', event.target.value);
  this.dispatchEvent(event);
}

不建议使用以下示例。

//Don’t do this
@api textValue;

handleTextInputChange(event) {
  this.textValue = event.target.value;
}

创建 FlowAttributeChangeEvent 实例

该事件使 LWC 能够通知运行时其当前状态。它是 Flow Runtime 状态管理机制的一部分。每当用户交互导致需要更新属性的修改时,都会触发这些事件。FlowAttributeChangeEvent@api

从模块导入。FlowAttributeChangeEventlightning/flowSupport

import { FlowAttributeChangeEvent } from "lightning/flowSupport";

接下来,您可以创建事件的实例。

const attributeChangeEvent = new FlowAttributeChangeEvent(apiParameterName, updatedValue);

FlowAttributeChangeEvent包括两个参数。

  • apiParameterName– 要修改的 API 属性的名称。
  • updatedValue– Flow 属性的更新值。

将字符串传递给与 JavaScript 和文件中显示的 API 属性匹配的字符串。apiParameterName.js-meta.xml

例如,请注意 how 在所有 3 个地方都是一致的:exampleApiParameterName

  • 在 LWC 的文件中声明属性:.js-meta.xml<property name="exampleApiParameterName" label="Example Api Parameter" .../>
  • 在 LWC 的文件中声明 API 属性:.js@api exampleApiParameterName;
  • 构造实例:FlowAttributeChangeEventconst changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", "newValue");

传递 以匹配文件中声明的数据类型。updatedValue.js-meta.xml

  • 将属性声明为 Record:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", { StringFieldName: "stringValue", BooleanFieldName: false, NumberFieldName: 42, DateTimeFieldName: "2022-12-15T23:35:24.000Z", });
  • 将属性声明为字符串:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", "newValue");
  • 将属性声明为数字:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", 6);
  • 将属性声明为布尔值:const changeEvent = new FlowAttributeChangeEvent("exampleApiParameterName", true);

触发 FlowAttributeChangeEvent 事件

构造实例后,可以使用该方法触发事件。FlowAttributeChangeEventthis.dispatchEvent(eventToFire)

const attributeChangeEvent = new FlowAttributeChangeEvent("apiPropertyName", 10);
this.dispatchEvent(attributeChangeEvent);

FlowAttributeChangeEvent 最佳实践

请遵循这些示例并避免有问题的用法,以减少流程版本升级后的意外行为。这些最佳实践使您能够更轻松地维护组件。FlowAttributeChangeEvent

  • 在事件处理程序或在事件处理程序中调用的方法中触发事件。
  • 将事件的 value 参数限制为以下数据类型:String、number、boolean、JSON(用于记录类型)。
  • 确保事件的 value 参数的 Flow 数据类型与 LWC 属性的数据类型匹配。@api
  • 在适当的情况下,通过使用 get/set 模式来响应对属性的更改。@api

此示例演示如何使用 getter 和 setter 对属性的更新进行计数,而不是在触发属性更改事件之前递增计数器。这两种模式都是有效的,但它们获得的结果略有不同。@api

@api textValue;
textValueToRender;
changeCounter = 0;

get textValue() {
  return this.textValueToRender;
}

// Due to the nature of the Flow Runtime, this setter method
// is called after the FlowAttributeChangeEvent fired below. It also
// is invoked when reactivity leads to a change to the textValue property.
set textValue(newTextValue) {
  this.changeCounter++;
  this.textValueToRender = newTextValue;
}

handleTextInputChange(event) {
  const event = new FlowAttributeChangeEvent('textValue', event.target.value);
  this.dispatchEvent(event);
}

在这种情况下,每当用户在文本输入中输入更改以及 Flow Runtime 确定属性已更改时,都会递增。这种方法考虑了组件初始化和通过反应性进行的跨组件交互。使用中间变量呈现来自 set 方法的更新。在此示例中,填充此角色。this.changeCountertextValuetextValueToRender

下面的代码示例在触发属性更改事件之前递增计数器。此方案不使用 get/set 模式。

@api textValue;
changeCounter = 0;

handleTextInputChange(event) {
  this.changeCounter++;
  const event = new FlowAttributeChangeEvent('textValue', event.target.value);
  this.dispatchEvent(event);
}

在这种情况下,每当用户在文本输入中输入更改时,都会递增。当反应性更改此字段的值时,计数器不会更新。this.changeCounter

使用无注释或属性来维护可修改的本地组件状态。@track

下面的示例演示一个颜色选取器,该选取器向用户显示输入文本框和一些色板。颜色选取器组件返回到流中,因此只需要注释。and 成员仅是内部成员,不需要任何装饰器。colorcolor@apiselectedSwatchIdinputValue

//colorPicker.js

@api color;

inputValue;
selectedSwatchId;


ALL_SWATCHES =[{
  'id': 1,
  'color': 'red'
}, {
  'id': 2,
  'color': 'blue'
}, {
  'id': 3,
  'color': 'green'
}, {
  'id': 4,
  'color': 'yellow'
}];

set color(newColor) {
  // Set the content of the input text to the color value:
  this.inputValue = newColor;

  // If the color matches a swatch, highlight it in the UI:
  const foundSwatch = this.ALL_SWATCHES.find(swatch => swatch.color === newColor);
  this.selectedSwatchId = foundSwatch && foundSwatch.id;
}

get color() {
  return this.inputValue;
}

handleSwatchSelected(event) {
  // Select get the swatch data for the clicked swatch:
  const selectedSwatch = this.ALL_SWATCHES.find(swatch => swatch.id === event.target.dataset.id);
  const changeEvent = new FlowAttributeChangeEvent('color', selectedSwatch.color);
  this.dispatchEvent(changeEvent);
}

handleInputValueChange(event) {
  this.inputValue = event.target.value;
  const changeEvent = new FlowAttributeChangeEvent('color', this.inputValue);
  this.dispatchEvent(changeEvent);
}

使用 get 方法将多个属性组合在一起,为视图构造派生变量。@api

//Salutation.js
@api firstName;
@api lastName;
@api ageName;

get salutation() {
  return `Hello ${this.firstName} ${this.lastName}, you are ${this.age} years old.`;
}
<!-- Salutation.html -->
<template>
  <div>{salutation}</div>
</template>

在参与内部组件状态管理所需的派生成员变量的每个属性的 set 方法中应用相同的逻辑,就像在比上一个示例更复杂的方案中一样。此逻辑可确保对任何贡献属性所做的更改都会导致值正确呈现,而不管设置属性的顺序如何。@api

//Dropdown.js
set optionLabels(newOptionLabels) {
  this.internalOptionLabels = newOptionLabels;
  this.options = this.computeOptions();
}

set optionValues(newOptionValues) {
  this.internalOptionValues = newOptionValues;
  this.options = this.computeOptions();
}

set value(newValue) {
  this.internalValue = newValue;
  this.options = this.computeOptions();
}

handleSelect(event) {
  const selectedValue = event.srcElement.value;
  const isAlreadySelected = this.options.some(option => {
    return option.isSelected && option.value === selectedValue;
  });

  if (!isAlreadySelected) {
    const attributeChange = new FlowAttributeChangeEvent('value', selectedValue);
    this.dispatchEvent(attributeChange);
  }
}

computeOptions() {
  if (this.internalOptionLabels.length !== this.internalOptionValues.length) {
    return [];
  }

  return this.internalOptionLabels.map((label, index) ==> {
    const value = this.internalOptionValues[index];
    const isSelected = this.internalValue === value;
    return {
      label,
      value,
      isSelected
    };
  });
}

不要修改属性。而是开火。@apiFlowAttributeChangeEvents

不要在构造后修改参数。默认情况下,实例是组合和冒泡的。FlowAttributeChangeEventFlowAttributeChangeEvent

const changeEvent = new FlowAttributeChangeEvent("prop", "value");
changeEvent.bubbles = false; // Don’t do this
changeEvent.composed = false; // Don’t do this

避免同时发生射击和事件,因为它可能导致争用条件。我们永远无法保证您的 Lightning Web 组件在导航过程开始时有时间呈现更新的值。FlowAttributeChangeEventsFlowNavigationXxx

派生属性最佳实践

在流组件中,派生属性是其值由同一组件的其他属性确定的属性。该值可能与一个或多个其他属性相关联。例如,数据表组件的参数是派生属性,因为它的值由属性的值确定。具体而言,参数的值是属性的第一个元素的值。firstSelectedRowselectedRowsfirstSelectedRowselectedRows

创建包含派生属性的流屏幕组件时,请遵循此处概述的最佳实践,以确保组件在响应式框架中正常运行。通过这些最佳做法,您可以避免与以下方面相关的问题:

反应性链

当对一个组件的属性进行更改导致对其他组件的属性进行级联更改时,就会发生反应链。例如,用户选择数据表组件中的一行,这将更改组件的属性值,从而更改 Name 组件的属性。对 Name 组件的更改会更改 Text 组件的属性。firstSelectedRowfirstNamevalue

在重新访问的屏幕上保留值

当管理员配置屏幕时,您可以选择在用户离开时流是否保留用户指定的值,然后使用“上一个”或“下一个”按钮返回到屏幕。

若要确保派生属性在具有反应性组件的流屏幕中按预期方式运行,请遵循以下准则:

  1. 务必在驱动更改的属性的方法中为派生属性触发事件。此外,在组件的方法中触发派生属性的事件,例如:FlowAttributeChangeEventsetFlowAttributeChangeEventconnectedCallback// 'Driving' attribute set method set stringToCount(newStringToCount) { this._stringToCount = newStringToCount; // Fire an event for 'derived' attribute const lengthChangeEvent = new FlowAttributeChangeEvent('stringLength', this._stringToCount.length); this.dispatchEvent(lengthChangeEvent); } connectedCallback() { // Fire an event for 'derived' attribute here as well const lengthChangeEvent = new FlowAttributeChangeEvent('stringLength', this.\_stringToCount.length); this.dispatchEvent(lengthChangeEvent); }
  2. 不要在方法中省略事件。 您必须将事件包含在两个位置。当流执行驱动更改的属性的 in 方法时,组件不在 DOM 中,事件基本上无处可去。在方法中添加事件可确保当流将组件添加到 DOM 时,流运行时可以使用该事件。FlowAttributeChangeEventconnectedCallbackFlowAttributeChangeEventFlowAttributeChangeEventsetconnectedCallback
  3. 不要在方法中省略事件。 触发驱动更改的属性的 in 方法可确保将更改应用于驱动更改的属性和派生属性。因此,包含自定义组件的反应性链可以正常工作。FlowAttributeChangeEventsetFlowAttributeChangeEventset
  4. 不要通过使用来延迟触发方法内部来省略该方法。 延迟可确保当流首次调用该方法时,组件位于 DOM 中。但是,延迟还意味着组件在流初始化屏幕后触发事件。因此,流运行时始终覆盖保留的值,并否决重新访问的值的设置。connectedCallbackPromise.resolve().then(...)FlowAttributeChangeEventsetFlowAttributeChangeEventsetset stringToCount(newStringToCount) { this._stringToCount = newStringToCount; const lengthChangeEvent = new FlowAttributeChangeEvent('stringLength', this._stringToCount.length); // This code overwrites preserved values. Don't do this. Promise.resolve().then(() => { this.dispatchEvent(lengthChangeEvent); }); }

导航更改事件最佳实践

除了 之外,您的 Lightning Web 组件还可以触发导航事件以在屏幕之间移动、暂停或完成流程。要使用导航事件,请从以下位置导入这些函数:FlowAttributeChangeEventlightning/flowSupport

  • FlowNavigationNextEvent
  • FlowNavigationBackEvent
  • FlowNavigationPauseEvent
  • FlowNavigationFinishEvent

触发 FlowNavigationEvent

此代码片段介绍如何导入和触发导航事件。当该示例使用 时,相同的结构适用于每个可用的导航目标。FlowNavigationNextEvent

import { FlowNavigationNextEvent } from "lightning/flowSupport";

export default class FlowExample extends LightningElement {
  handleCustomNavigationButtonClick() {
    const nextEvent = new FlowNavigationNextEvent();
    this.dispatchEvent(nextEvent);
  }
}

导航事件允许您的 Lightning Web 组件包含其他控制机制。对最终用户交互做出反应时触发导航事件。使用导航事件时,请参阅以下准则:

  • 在事件处理程序(或事件处理程序调用的方法中)触发导航事件。
  • 不要在事件处理程序之外触发导航事件,因为这会导致糟糕的用户体验。
  • 不要在生命周期处理程序(如 和)中触发导航事件。renderedCallbackconnectedCallback
  • 将跳过屏幕的逻辑放在 Flow Decision Nodes 中,而不是放在屏幕的生命周期中。
  • 不要在虚拟屏幕中执行导航,因为这可能会导致 Flow 性能不佳。
  • 如果您遇到以下情况:由于数据尚不可用于 Flow Decision Nodes,因此必须在屏幕的初始化阶段完成导航,请在 Idea Exchange 中发布升级请求

在 Salesforce Targets 中使用组件

了解如何在不同的目标中使用 Lightning Web 组件,包括 Lightning Experience、Salesforce 移动应用程序和 Experience Builder 站点。

查看组织中的 Lightning 组件列表

在设置中,查看组织中 Lightning Web 组件和 Aura 组件的列表。

在“设置”中,输入“快速查找”框,然后选择“Lightning 组件”。在此页面中,您可以:Lightning Components

  • 查看组织中的 Lightning Web 组件和 Aura 组件。
  • 查看组件详细信息。单击组件名称或标签。
  • 在开发者控制台中打开 Aura 组件。单击组件名称,然后单击 Developer Console。

注意

要开发 Lightning Web 组件,请使用 Salesforce CLI 和您选择的代码编辑器。请参阅设置开发环境。

在 AppExchange上分发组件

作为 ISV 或 Salesforce 合作伙伴,您可以打包组件并将其分发给 AppExchange(Salesforce 商店)上的其他 Salesforce 用户和组织。

将组件添加到托管包

托管包可确保应用程序和其他资源完全可升级。

要创建和使用受管软件包,请使用 Developer Edition 组织并注册名称空间前缀。托管包在组件名称中包含命名空间前缀,可防止安装程序组织中的命名冲突。

注意

自定义 Lightning Web 组件无法引用从托管软件包安装的 Lightning Web 组件。请参阅组件命名空间。

要将组件添加到包中,请参阅 Salesforce 帮助中的将组件添加到包中。

将组件添加到包中时,将自动包含该组件引用的其他组件以及导入的任何资源。有关详细信息,请参阅@salesforce模块。@salesforce/*

发布包后,组件名称将被锁定,但包开发人员仍然可以在组件的配置文件中编辑这些值。

  • apiVersion
  • description
  • isExposed(只能更改为falsetrue)
  • masterLabel
  • targetConfigs
  • targets

如果 is ,包开发人员可以从组件中删除配置和 public () 属性。isExposedfalsetargets@api

如果是,并且组件位于已发布的托管包中,则包开发人员无法从组件中删除配置或 public () 属性。即使目标或公共属性是在包的最近发布之后添加的,也会强制执行此限制。isExposedtruetargets@api

从托管包中删除组件

发布托管包后,可以决定重构包并删除组件。您有责任让客户了解您删除的任何组件的潜在影响。在升级程序包的发行说明中,列出已删除的所有自定义组件,并通知客户任何必要的操作。

注意

若要在打包组织中启用组件删除,请在合作伙伴社区中记录案例。

要从托管包中删除组件,请执行以下操作:

  1. 在“设置”中,输入“快速查找”框。Lightning Components
  2. 选择 Lightning 组件
  3. 单击要删除的组件的 Del

注意

当您从软件包中删除 Lightning Web 组件时,该组件将在订阅者安装升级后的软件包后保留在订阅者的组织中。如果需要,订阅者组织的管理员可以删除该组件。

当您删除值为 的 Lightning Web 组件时,我们建议采用两阶段过程,以确保已删除的组件不依赖于包中的其他项目。isExposedtrue

第一阶段:删除引用。

  1. 编辑要删除的 Lightning Web 组件,以删除对其他 Lightning Web 组件的所有引用。
  2. 上传新的包版本。
  3. 将第一阶段升级推送给订阅者。

第二阶段:删除过时的组件。

  1. 从软件包中删除 Lightning Web 组件。
  2. (可选)删除其他相关组件和类。
  3. 上传新的包版本。
  4. 将第二阶段升级推送给订阅者。

使用托管包中的组件

托管包可以为您的组织提供有用的功能。某些托管软件包包括托管的 Lightning Web 组件。通过 AppExchange 安装托管软件包后,您可以通过在自定义组件中使用托管软件包来引用托管软件包中包含的托管 Lightning Web 组件 (LWC)。

重要

托管包的作者必须同时使用 Locker 和 LWS 进行测试,以确保其组件在这两种环境中都能正常工作。我们建议先在沙盒中安装和测试托管软件包,然后再将其安装到生产组织中。

在自定义组件中使用托管 LWC

托管软件包中的 Lightning Web 组件具有与您自己的命名空间不同的命名空间。我们建议您参考有关托管包的文档。

在自定义组件中使用托管包中的 LWC 时,请使用烤肉串大小写(短划线分隔)。同样,您在 LWC HTML 模板中使用的全局属性必须使用 kebab 大小写。

例如,如果托管包在命名空间中包含 LWC,并且托管组件名称为 ,则可以像这样引用该组件。lwc_partneraccount-verification

<!-- myComponent.html -->
<template>
  <lwc_partner-account-verification attribute-name="value"> </lwc_partner-account-verification>
</template>

在 Salesforce Target 中使用托管 LWC

托管 LWC 可用于不同的 LWC 目标,您可以使用相应的托管包文档进行验证。例如,如果在自定义 LWC 中使用托管 LWC,则可以通过更新配置标记在各种目标中显示托管 LWC。<targets>

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>58.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightning__RecordPage</target>
    <target>lightning__AppPage</target>
    <target>lightning__HomePage</target>
  </targets>
</LightningComponentBundle>

Lightning 应用程序生成器
使用点击式工具开发可用于为 Lightning Experience 和 Salesforce 移动应用程序快速构建自定义页面的组件。

为 Lightning 应用程序生成器配置组件

在 Lightning 应用程序生成器的 Lightning 页面上使用自定义 Lightning Web 组件之前,需要执行几个步骤。

1. 在配置文件中定义组件元数据

componentName.js-meta.xml 文件定义组件的元数据值,包括用于 Lightning 应用程序生成器的组件的设计配置。编辑配置文件以:

  • 使您的组件可在 Lightning 应用程序生成器和托管软件包中使用。
  • 定义您的组件可用于哪些类型的 Lightning 页面。
  • 配置组件的属性。
  • 设置组件支持的对象。

请参阅 XML 配置文件元素的完整列表。

此示例配置文件使该组件可用于所有 Lightning 页面类型,但限制仅对帐户、商机和仓库对象的记录页面支持。该组件具有为记录页面定义的一组属性,而不是为应用程序和主页定义的属性。

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>47.0</apiVersion>
  <isExposed>true</isExposed>
  <masterLabel>Best Component Ever</masterLabel>
  <description>This is a demo component.</description>
  <targets>
    <target>lightning__RecordPage</target>
    <target>lightning__AppPage</target>
    <target>lightning__HomePage</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__RecordPage">
      <property name="prop1" type="String" />
      <objects>
        <object>Account</object>
        <object>Opportunity</object>
        <object>Warehouse__c</object>
      </objects>
    </targetConfig>
    <targetConfig targets="lightning__AppPage, lightning__HomePage">
      <property name="prop2" type="Boolean" />
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

注意

定义组件属性时,请确保在文件和配置文件中为其分配了相同的类型(String、Integer、Boolean)。如果分配的类型不匹配,则配置文件中的类型分配优先。.js

2. 选项:将 SVG 资源添加到组件包中

要在 Lightning App Builder 中将 SVG 资源作为组件的自定义图标包含在内,请将其添加到组件的文件夹中。它必须被命名为 。每个文件夹只能有一个 SVG。componentName.svg

在 Lightning 应用程序构建器中配置用于动态交互的组件

管理员和开发人员都需要使动态交互正常工作,但 keystone 是一个自定义源组件,用于定义要触发的事件的属性。将事件元数据和属性添加到源组件,以将事件公开给 Lightning 应用程序构建器,然后管理员可以在其中配置事件的目标和交互。

只有 Lightning Web 组件可以是源组件,但任何组件(Aura 或 LWC)都可以成为目标。若要公开源组件中的事件,请在其文件中触发标准 JavaScript CustomEvent。若要使事件可被发现,请在组件文件中使用特定于动态交互的元数据,类似于生成器属性的公开方式。.jsjs-meta.xml

注意

有关动态交互的概述,请参阅 Salesforce 帮助。

使用动态交互公开事件

动态交互使用两个子标签,您可以将这两个子标签放入源组件包的 componentName.js-meta.xml 文件中以公开事件。targetConfig

  • event
  • schema

注意

这些子标签仅适用于目标 .targetConfiglightning__AppPage

下面是帐户列表源组件的示例配置文件。它包括一个事件,其架构包括文件中定义的 和。js-meta.xmlitemselectedapiNamerecordId.js

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>52.0</apiVersion>
  <isExposed>true</isExposed>
  <masterLabel>Account List</masterLabel>
  <targets>
    <target>lightning__AppPage</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__AppPage">
      <property name="apiName" type="String"/>
      <property name="listViewApiName" type="String"/>
      <event name="itemselected" label="Item Selected" description="This event fires when an item is selected.">
        <schema>
          {
            "type": "object",
            "properties": {
              "recordId": {
                "type": "string",
                "title": "Record ID"
                "description": "Enter an 18-digit record ID."
          },
              "apiName": {
                "type": "string"
              }
            }
          }
        </schema>
      </event>
    </targetConfig>
  </targetConfigs>
  <description>meta xml description</description>
</LightningComponentBundle>

.js-meta.xml 文件的注意事项

  • 动态交互仅使用架构和架构。架构中的所有其他项都将被忽略。typeproperties
  • 唯一支持的属性特性是 、 和 。typetitledescription
  • 在事件架构中,支持的唯一有效属性类型是 String、Integer 和 Boolean。
  • 不会针对文件验证标记元数据。event.js

使用 Lightning 应用程序生成器的提示

在创建要在 Lightning 应用程序生成器中公开的组件时,请牢记这些准则。

组件提示

  • 使组件填充其显示区域的宽度(包括边距)的 100%。请参阅使组件具有宽度感知能力。
  • 如果组件需要交互,请在 Lightning 应用程序生成器中提供适当的占位符行为。
  • 不要显示空白框。想想其他网站是如何工作的。例如,Facebook 在实际的源项从服务器返回之前显示源的轮廓。大纲改进了用户对 UI 响应能力的感知。
  • 如果组件依赖于触发的事件,请为其指定在事件触发之前显示的默认状态。
  • 使用 Salesforce Design System 设置组件样式。

配置文件提示

  • 使用配置文件中的标记为组件设置友好名称。masterLabel
  • 使用配置文件向 Lightning 应用程序生成器公开属性。
  • 我们强烈建议在所有组件的配置文件中包含支持的外形规格信息。
  • 为所有属性指定一个具有友好显示名称的标签。
  • 提供说明以解释预期数据和任何准则,例如数据格式或预期值范围。描述文本在 Lightning 应用程序生成器的属性编辑器中显示为工具提示。
  • 为所需的属性提供默认值。将具有必需属性且没有默认值的组件添加到应用程序构建器时,该组件将显示为无效,这是一种糟糕的用户体验。
  • 对任何公开的属性使用基本支持的类型(字符串、整数、布尔值)。
  • 定义组件属性时,请确保在文件和配置文件中为其分配了相同的类型(String、Integer、Boolean)。如果分配的类型不匹配,则配置文件中的类型分配优先。.js
  • 指定整数属性的 min 和 max 属性,以控制接受值的范围。
  • 字符串属性可以为数据源提供一组预定义值,允许属性将其配置公开为选择列表。
  • 如果在 Lightning 页面或托管软件包中使用组件,我们会阻止您进行可能破坏组件的破坏性更改。这些破坏性变化的一些示例是:
    • 如果组件正在该对象的记录页面上使用,则删除该对象标签。
    • 如果组件正在该类型的页面上使用,则删除页面类型支持。
    • 如果组件正在 Lightning 页面上使用,则更改 min 或 max 属性值。

局限性

  • Lightning 应用程序构建器不支持地图、对象或 java:// 复杂类型。
  • 在 Lightning 页面上使用组件后,您只能增加该组件支持的外形规格,而不能减小它们。
  • 拉取刷新不适用于 Salesforce 移动应用程序中的自定义 Lightning Web 组件。