// 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
}
}
// 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
}
}
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
});
}
}
// 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
// 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
// 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
);
}
}
lightning/pageReferenceUtils 模块提供了 and 函数,用于将默认字段值编码为字符串并对其进行解码。将编码字符串分配给页面引用中的属性。encodeDefaultFieldValues()decodeDefaultFieldValues()pageReference.state.defaultFieldValuesstandard__objectPage
该调用将创建一个带有“Press Me!”标签的按钮。该按钮入到 ID 为 的 DOM 元素中。在页面上添加按钮并处于活动状态后,将调用回调函数并执行语句。回调接收创建的组件作为其唯一参数。在这个简单示例中,该按钮未配置为执行任何操作。$Lightning.createComponent()lightningvfconsole.log()
<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>
若要获取记录 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",
},
});
}
}
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));
}
}
<!--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>
// 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);
}
}
}
<!--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>
// 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;
}
}
<!--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>
<!--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>
<!---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 || [];
}
_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 || {};
}
// 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 及更高版本中可用。
对于您设置的每个变量,请提供变量的名称、类型和值。对于 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 }
]
}
// 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,
},
];
}
}
}
// 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
}
}
// 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;
}
}
// 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;
}
}
}
通知运行时属性更改。Lightning Web 组件使用事件来报告从组件到流程的更改。为了通知流运行时属性更改,组件会触发事件。例如,在满足条件时使用条件可见性呈现屏幕组件时,或者将输出属性的值映射到流变量时,请使用此事件。有关代码示例,请参见。FlowAttributeChangeEventlightning-flow-support
设置屏幕流组件的反应性
屏幕流反应性意味着使屏幕流组件更改影响另一个同一屏幕组件。
在 Flow 构建器中添加和配置自定义 Lightning Web 组件之前,请创建自定义 LWC。
如果您计划构建反应式屏幕组件或使用支持的组件,则需要了解每个组件的注意事项。反应性包括:
确定哪个屏幕组件是源,哪个组件是反应式组件。
了解每组组件的不同交互。
示例:标准流量组件到标准流量组件
使用标准 Flow 组件是实现反应性的最简单方法。
使用标准 Flow 组件,您可以添加组件,为每个组件提供 API 名称和标签(如果需要),标识源和反应式组件,然后保存并运行流。
要使 Name 组件的 First Name 字段响应并显示来自 Text 组件的所有文本输入,请执行以下操作:
在流程中,添加组件和组件,并为每个组件提供标签。TextName
在组件的 First Name’s source 字段中,选择组件作为源。源可以是同一类型的任何组件,在本例中,Text 组件的类型和 Name 组件的 First Name 字段的类型为 String。NameText
保存并运行 Flow,然后在组件的输入中键入 .键入每个字符后,“名字”字段会立即更新。TextThis is Reactivity
示例:标准流组件到自定义 Lightning Web 组件
让您的自定义组件对标准 Flow 组件中的更改做出反应。
要创建自定义组件并将其添加到 Flow Builder 中,请执行以下操作:colorName
添加“文本”组件和“自定义”组件,并为每个组件提供标签。colorName
在 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;
}
}
@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
//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.`;
}
const changeEvent = new FlowAttributeChangeEvent("prop", "value");
changeEvent.bubbles = false; // Don’t do this
changeEvent.composed = false; // Don’t do this
避免同时发生射击和事件,因为它可能导致争用条件。我们永远无法保证您的 Lightning Web 组件在导航过程开始时有时间呈现更新的值。FlowAttributeChangeEventsFlowNavigationXxx
务必在驱动更改的属性的方法中为派生属性触发事件。此外,在组件的方法中触发派生属性的事件,例如: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); }
不要在方法中省略事件。 您必须将事件包含在两个位置。当流执行驱动更改的属性的 in 方法时,组件不在 DOM 中,事件基本上无处可去。在方法中添加事件可确保当流将组件添加到 DOM 时,流运行时可以使用该事件。FlowAttributeChangeEventconnectedCallbackFlowAttributeChangeEventFlowAttributeChangeEventsetconnectedCallback
不要在方法中省略事件。 触发驱动更改的属性的 in 方法可确保将更改应用于驱动更改的属性和派生属性。因此,包含自定义组件的反应性链可以正常工作。FlowAttributeChangeEventsetFlowAttributeChangeEventset
不要通过使用来延迟触发方法内部来省略该方法。 延迟可确保当流首次调用该方法时,组件位于 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