Flows 流程 — LWC Flow 组件完全指南

全面掌握 LWC 在 Flow 中的使用。涵盖配置 Flow Screens、嵌入 lightning-flow、输入/输出变量、完成行为/恢复面试、四种响应式模式、FlowAttributeChangeEvent 状态管理、派生属性最佳实践、导航事件。...

📅 2026/7/19 ✍️ ponybai 🏷️ lwc, salesforce

Flows(流程)

Flows

Flow Builder 让管理员通过流程自动化业务流程。LWC 可作为流程屏幕组件自定义 UI用于 Flow Builder。本章涵盖配置、嵌入、输入/输出变量、完成行为控制、恢复暂停的面试、响应式屏幕组件和状态管理最佳实践。

配置组件以支持 Flow Screens

配置 Flow Screens

添加 lightning__FlowScreen target 使组件可用于流程屏幕。需在 JS 中同步定义 @api 属性和默认值:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle>
  <apiVersion>47.0</apiVersion>
  <isExposed>true</isExposed>
  <masterLabel>Best Component Ever</masterLabel>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <targetConfigs>
    <targetConfig targets="lightning__FlowScreen">
      <property name="startDate" label="Start Date" type="Date" role="inputOnly"/>
      <!-- inputOnly——用户可设置,不从页面设值 -->
      <property name="account" label="Account" type="@salesforce/schema/Account"/>
      <property name="annualRevenue" label="Annual Revenue" type="Integer" role="outputOnly"/>
      <!-- outputOnly——只读,仅输出 -->
      <property name="name" label="Account Name" type="String" default="New Account"/>
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

// JS——必须定义默认值以在运行时生效
@api startDate; @api account; @api annualRevenue;
@api name = 'New Account';

role 属性:inputOnly——仅输入;outputOnly——仅输出(只读)。默认不设 role 允许输入输出双向。所有输入属性默认也是输出属性

运行时三个关键注意事项:① 管理员未设默认输入值→Flow Builder 传 null→需处理 null 设运行时默认值。② 屏幕组件隐藏时→所有输出属性设为 null(导航离开时)。③ 用 FlowAttributeChangeEvent 通知运行时属性变化——用于条件可见性和输出属性映射到 Flow 变量。

嵌入 Flow —— 创建、启动与输入变量

嵌入 Flow

使用 lightning-flow 基础组件在任何 LWC 中嵌入 Screen Flow。仅支持激活的流程。含自定义 LWC 或 Aura 组件的流程不能用于 LWR 的 Experience Cloud 站点。

<lightning-flow flow-api-name="Survey_customers"></lightning-flow>

// 带输入变量和状态处理
<lightning-flow flow-api-name={flowName}
    flow-input-variables={inputVariables}
    onstatuschange={handleStatusChange}></lightning-flow>

// 输入变量——{ name, type, value } 对象数组
get inputVariables() {
  return [
    { name: 'OpportunityID', type: 'String', value: this.opportunityId },
    { name: 'AccountID', type: 'String', value: this.accountId },
    { name: 'numVar', type: 'Number', value: 30 },
    { name: 'account', type: 'SObject', value: { 'Id': this.accountId, 'Rating': 'Warm' } },
    { name: 'dateColl', type: 'String', value: ['2016-10-27', '2017-08-01'] }
  ];
}

// onstatuschange 事件参数:status/flowTitle/helpText/outputVariables/guid/activeStages/currentStage
// status: STARTED | PAUSED | FINISHED | FINISHED_SCREEN | ERROR

仅允许输入访问的变量可设置——引用不允许输入访问的变量设置会被忽略。类型用 Flow 数据类型的 API 名(Record→SObject、Text→String)。

控制完成行为与恢复暂停的面试

完成行为与恢复

自定义完成行为

默认点击 Finish→重新开始新面试。用 onstatuschange 自定义:检测 status === "FINISHED" → 重定向到其他页面(NavigationMixin)或显示 Toast。获取输出变量:event.detail.outputVariables——遍历找到目标变量(如 "redirect" 记录 ID)→ 导航到记录页。

恢复暂停的面试

默认用户从主页的 Paused Interviews 组件恢复。自定义方案——嵌入 lightning-flow + flow-interview-id 属性:

<lightning-flow flow-api-name={flowName} flow-interview-id={pausedInterviewId}></lightning-flow>

// Apex 查询暂停的面试——SOQL FlowInterview
@AuraEnabled(cacheable=true)
public static String getPausedId() {
  List interviews = [SELECT Id FROM FlowInterview
    WHERE CreatedById = :UserInfo.getUserId() AND InterviewLabel LIKE '%Survey customers%'];
  return interviews.isEmpty() ? null : interviews.get(0).Id;
}
// null → 启动新面试 | 有 ID → 恢复该面试

响应式屏幕 Flow —— 概述与标准到标准

响应式概述

屏幕 Flow 响应式:一个组件的变更自动影响同屏另一个组件。核心概念——确定源组件(数据来源)和响应式组件(被影响的组件)。

标准→标准(最简单):Text 组件 → Name 组件的 First Name 字段。在 Name 组件属性中选择 Text 组件作为源——同类型自动匹配。用户输入每个字符→Name 组件实时更新。

标准→自定义 LWC:Text 组件作为 colorName 自定义组件的 Name of Color 属性的源。colorName 组件用 @api color 接收值→getter 返回内联样式→显示同色文本。

响应式模式 —— 标准到自定义与自定义到标准

响应式模式

自定义→标准(关键——派发 FlowAttributeChangeEvent):

import { FlowAttributeChangeEvent } from "lightning/flowSupport";

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

handleInputChange(event) {
  this.dispatchEvent(new FlowAttributeChangeEvent("customTextValue", event.target.value));
}
// 事件名必须与 @api 属性名一致!Flow Builder 中 Text 组件的源设为此自定义属性

核心原则:不要直接修改 @api 属性——派发 FlowAttributeChangeEvent 让 Flow Runtime 管理状态。Flow Runtime 在事件派发后再调用 setter。这保持了清晰的父-子控制关系——组件请求变更,Runtime 批准后更新。

响应式模式 —— 自定义到自定义与最佳实践

自定义到自定义

自定义→自定义:customText 组件作为 colorName 组件的源——在 colorName 属性中选择 customText 的 customTextValue 属性。完全相同的模式——customText 派发 FlowAttributeChangeEvent → Flow Runtime 传递值给 colorName。

FlowAttributeChangeEvent 构建:new FlowAttributeChangeEvent(apiParameterName, updatedValue)。参数名在 .js / .js-meta.xml / 事件构造函数中三处保持一致。值类型匹配 .js-meta.xml 声明:String→字符串、Number→数字、Boolean→true/false、Record→JSON 对象。

最佳实践:在事件处理器或处理器调用的方法中派发、限制值类型为 String/number/boolean/JSON(Record)、确保 Flow 数据类型与 @api 属性匹配、用 get/set 模式响应变化。

状态管理与派生属性最佳实践

状态管理

LWC vs Aura 状态管理

Aura 中 <aura:attributes> 可被外部修改。LWC 设计为清晰分离内部/外部状态——@api 属性仅由父组件修改、@track 和无注解变量为内部状态。

Flow Runtime 状态管理

点击 Next/Finish → Runtime 提取每个组件的当前 @api 属性状态后再前进。组件不应修改自己的 @api 属性——通过 FlowAttributeChangeEvent 请求变更。此模式使组件更易重用、Runtime 维护准确状态、支持条件可见性等跨组件交互。

// ✅ 推荐——getter/setter 模式 + FlowAttributeChangeEvent
@api textValue;
handleTextInputChange(event) {
  this.dispatchEvent(new FlowAttributeChangeEvent('textValue', event.target.value));
}

// ❌ 不推荐——直接修改 @api
handleTextInputChange(event) { this.textValue = event.target.value; }

derived attribute(派生属性)最佳实践

派生属性——值由同组件其他属性决定的属性(如 Data Table 的 firstSelectedRowselectedRows 派生)。需同时处理响应式链条和重访屏幕保留值两个问题。

  1. 必须在驱动属性的 set 方法和 connectedCallback 中派发 FlowAttributeChangeEvent——set 时组件不在 DOM(事件无目标),connectedCallback 确保 Runtime 能消费
  2. 不要省略 connectedCallback 中的事件——否则重访屏幕时值被覆盖
  3. 不要省略 set 中的事件——否则响应式链条断裂
  4. 不要用 Promise.resolve().then(...) 延迟 set 中的事件——会覆盖保留值

导航事件与组件模式

导航事件

导入四种导航事件:FlowNavigationNextEventFlowNavigationBackEventFlowNavigationPauseEventFlowNavigationFinishEvent

import { FlowNavigationNextEvent } from "lightning/flowSupport";
handleCustomNavigation() {
  this.dispatchEvent(new FlowNavigationNextEvent());
}

getter/setter 模式——计数更新示例

// ✅ getter/setter 模式——setter 在事件后调用,响应式变更时也触发
@api textValue; textValueToRender; changeCounter = 0;
set textValue(newTextValue) { this.changeCounter++; this.textValueToRender = newTextValue; }
get textValue() { return this.textValueToRender; }
handleTextInputChange(event) {
  this.dispatchEvent(new FlowAttributeChangeEvent('textValue', event.target.value));
}
// changeCounter 在每次用户输入 + 每次响应式变更时递增

// 对比——直接修改@api(不推荐):changeCounter 仅在用户输入时递增

colorPicker 完整示例——内部状态用无注解属性:@api color 对外公开;inputValue/selectedSwatchId 为内部状态无需装饰器。setter 中同步 inputValue 和选中色板;点击色板或输入文本→派发 FlowAttributeChangeEvent。用 get 方法组合多个 @api 属性构造派生展示变量(如 salutation = Hello firstName lastName, you are age years old.)。

导航事件指南:在事件处理器中派发(非 lifecycle hooks)、不在 renderedCallback/connectedCallback 中派发、跳过屏幕的逻辑放 Flow Decision Nodes 而非屏幕生命周期、不用 dummy screen 导航(性能差)。不要修改 FlowAttributeChangeEvent 的 bubbles/composed 属性。不要同时派发 FlowAttributeChangeEvent 和 FlowNavigationXxx 事件——竞态条件。不要在派发导航事件后写后续代码——导航立即离开当前屏幕。

感谢阅读本指南。如需继续学习,请参阅下一章:使用 LWC 创建 Flow 本地操作。