DEX475

Create Flow Local Actions using LWC

课程介绍

同学们,今天我们聊聊在 Flow 里怎么让组件直接在前端“干活”——也就是,本地操作,。你想想,很多场景我们完全不需要跟服务器来回通信,比如调用一个外部的天气 API、打开一个新网页、或者在屏幕右下角弹出一个“操作成功”的 Toast 提示。这些动作,都可以在用户浏览器里秒完成,体验特别流畅。 但要记住,这种本地操作类组件跑在 Lightning 收件箱(Lightning Runtime)里,,只有屏幕流能用,,因为需要浏览器环境,自动化流、记录触发的流那是没有页面的,所以不行。而且组件本身也必须遵守 Lightning 收件箱的一些安全限制,不能为所欲为。 那我们要怎么做一个本地操作的 LWC 呢?整个生命周期大概分这几步—— ,第一步,配置目标。, 在组件的 `*-meta.xml` 文件里,必须把目标设为 `lightning__FlowAction`。只有这样,Flow Builder 才会把它识别成一个“操作”类型的组件。 ,第二步,实现核心方法 invoke()。, Flow 运行时调用我们的组件,就是触发这个 `invoke()` 方法。你可以把它写成一个同步的方法,直接返回结果;但更常见的,我们会返回一个 ,Promise,,比如去发一个 fetch 请求拿第三方数据,然后再告诉 Flow 我完事了。同时,Flow 会传给你一个 `cancelToken`,万一这个操作超时或者被中断了,你可以在 Promise 里检测到,主动中止,避免一直在那傻等。 ,第三步,如果这是个屏幕组件,还要做验证。, 有时候本地操作组件是放在屏幕上的,用户可能输入了一些东西,这时候就需要前端校验。LWC 里可以用 `validate()` 方法做整体检查;如果你想手动标记某个字段出错,可以用 `setCustomValidity('错误信息')`,再用 `reportValidity()` 让浏览器把提示显示出来,跟原生 HTML 校验一样。 ,还有一点很酷,就是自定义属性编辑器。, 你肯定希望管理员在 Flow Builder 里配置这个操作时,看到的不是一堆死板的文本框,而是下拉列表、切换开关之类的。这时候你可以提供一个 ,JavaScript 接口,,里面包括 `inputVariables`、`builderContent`、`elementInfo` 和 `genericTypeMappings` 这些对象,去描述编辑器的长相和逻辑。这样非开发者也能轻松配置你的组件。 最后别忘了,类型映射,——Flow 里的数据类型跟 JavaScript 的类型不是一回事儿。比如 Flow 里的 Text 对应到 LWC 就是字符串,Number 对应数字,Boolean 对应布尔,Date/DateTime 都有对应的对象。你得清楚这些对应关系,避免传值出错。 总结一下,今天讲的本地操作就是给你在 Flow 里打开了一扇“无服务器”的窗:不用 Apex,不用等服务器,直接在用户眼前把事办了。关键记住:目标设对、invoke 实现好、超时要处理、验证别忘、编辑器做好、类型要匹配。这样你就能做出既灵活又可靠的本地操作组件啦。 咱们下次课再见!

课程章节

本课程共有 8 个章节

  • 1

    Flow Local Actions — Configuration & invoke()

    第 352 页

    今天我们来聊聊Flow里的“本地操作”,也就是Local Actions。你可以在js-Meta.html里配置,把目标设为lightning__FlowAction。它的模板是空白的——因为本地操作根本不需要界面,它只负责在后台执行逻辑。 当一个操作被触发时,流运行环境会调用它的invoke()方法。如果是同步的操作,非常简单:做你要做的事,然后直接返回就行了。方法一结束,流里的下一个元素就自动往下走。 但很多时候,我们的操作是异步的,比如发一个网络请求。这时,invoke()就要返回一个Promise。如果Promise变成resolve,流就顺利进入下一个元素;要是变成rejected,流就会跳转到故障连接器,并且自动把错误信息放到$Flow.FaultMessage变量里,让你能自定义报错内容。 还有一个实用的小细节:Flow会给你一个cancelToken参数,用来处理超时。它的默认超时时间是120秒,如果操作太久没完成,这个Promise会被自动解决,给你机会去做一些清理工作,同时也能设置一个更友好的自定义错误消息。 另外,如果你的操作需要调用外部服务器的接口,那就要注意了:必须配置好CORS(跨域资源共享),而且在Salesforce组织里要把那个服务器的地址添加进白名单。不然请求是发不出去的。 还有一点要提醒:如果你在Lightning Web Runtime(LWR)站点上用,就别用老的platformShowToastEvents了,改用lightning/toast模块来显示提示消息。 总结一下:本地操作没有界面,invoke是入口,同步直接返回,异步返回Promise并处理好resolve和reject,利用cancelToken做超时,注意CORS和LWR站点的提示方式。这样,你就能让Flow在后台灵活地调用自定义逻辑了。

    查看详情
  • 2

    Validate Custom Flow Screen Components

    第 353 页

    同学们,今天咱们来聊一个在Salesforce流中非常实用的知识点——流量屏幕的验证机制。简单说,就是当用户在流程的界面上输入信息时,我们如何优雅地告诉系统“这个值对不对”,以及“如果不对,怎么显示错误”。 在Lightning Web Components里处理这件事,我们会用到三个协调配合的方法,它们像一个工作小组,分工明确。 首先,我们有个,validate(), 方法。它的任务是返回一个对象,包含`isValid`和`errorMessage`。这个方法是内部状态的评判官,当流程导航(比如点击“下一步”)时,系统会自动调用它,问组件:“嘿,你自己觉得现在输入的内容有效吗?”如果有效,`isValid`就是`true`;如果无效,就返回`false`,并且附上`errorMessage`说明错在哪儿。注意一点:这个方法千万不能用箭头函数来写,必须用普通的方法定义语法,否则`this`指向会出问题,我们后面在代码里会看到。 接着,系统不可能只看你自己的报告,外部的验证错误也会送进来——比如用户在输入框里填了不符合规则的数据,平台层会抛过来一个错误。这时候,,setCustomValidity(), 就上场了。它专门用来接收这些外部错误,像个小仓库,把这些错误信息先存起来,但并不会马上显示,因为可能还没到渲染的时候。 那什么时候真正显示所有错误给用户看呢?轮到,reportValidity(), 出场了。它就像汇报员,当需要把内部和外部的错误一次性展示出来时,系统就会调用它。然后它负责把积累的错误信息渲染到HTML页面上,用户就能直观看到哪里出错了。 为了让大家更好理解,我们看一个完整的例子:,numberOfStudents, 组件。这个组件演示了一套实用的验证模式。它里面用一个叫`hasUserInteracted`的布尔标志,来跟踪用户到底有没有操作过界面。为什么要这样?因为如果用户还没开始填,我们就弹错误,体验很差。所以,只在用户交互之后,才在属性的,setter,里进行验证。一旦值变了,还主动触发`FlowLocalChangeEvent`事件,确保流程能感知到变化,保持响应式更新。 错误信息我们也会用更友好的方式呈现,这里通过`@salesforce/label`导入自定义的标签,这样文案容易管理和翻译。最后,展示错误时,我们把外部错误放在一个`lightning-formatted-rich-text`富文本区域,和内部错误对应的`div`一起,都放在输入框的上方。这样用户一眼就能看到清晰的反馈,知道问题在哪里。 所以总结一下:validate帮你自查,setCustomValidity接收外部批评,reportValidity统一汇报。再结合交互标志、事件通知和富文本展示,就能打造出一个既可靠又友好的流屏幕验证体验。大家在后续开发中,可以照这个模式来搭建自己的验证逻辑。今天的课就到这里,有什么问题随时提出来。

    查看详情
  • 3

    Validation Methods — Timeline & Decision Table

    第 354 页

    好,咱们现在来看一下验证方法的时间轴,以及这张决策表到底在说什么。这张表其实就是在完整地告诉你,每个验证方法什么时候会被调用,以及在不同情况下,它们会做什么。 第一次页面加载的时候,如果有任何错误,不管是来自系统内部的校验,还是你通过代码设置的外部错误,都会立刻调用 reportValidity 这个方法,把错误信息直接展示出来。也就是说,一上来就让你看到哪里有错。 但之后的每一次触发,比如用户修改输入、或者组件重新渲染时,行为就变得复杂一点了,它会根据三样东西来决定怎么做:上一次有没有外部错误、当前有没有新的外部错误、以及当前内部的 validate 方法有没有检查出错误。 这里有两个最主要的场景你需要记住。 第一个场景,当存在外部错误的时候,我们会先调用 setCustomValidity,把外部错误的消息传给它存起来,然后紧接着调用 reportValidity 去把这个消息渲染出来。也就是说,只要外面告诉你“这个字段有问题”,就立刻显示这条消息。 第二个场景,当仅有内部错误的时候,也就是说用户自己的输入不满足规则,但没有外部指定的自定义错误,我们会先给 setCustomValidity 传一个空字符串,这个动作会把之前可能缓存的外部错误清掉。然后调用 reportValidity,这时候它会重新计算内部 validate 方法的结果,把内部发现的错误直接呈现出来。 那这个模式背后有一个很清晰的实现思路,就是要把“存储错误消息”和“渲染错误消息”这两件事分开。setCustomValidity 的职责是,如果它被调用并且组件正在显示的话,它应该马上更新显示,但同时永远都要把消息缓存起来。而 reportValidity 的职责是,把缓存的外部消息应用上,并且重新触发内部验证,再决定最终显示什么。 这样分开处理之后,就能很好地跟 Flow 运行时配合工作了。因为 Flow 引擎有时候会先存消息,有时候会立刻要渲染,这种存储和渲染的解耦可以确保在各种复杂流程下,错误提示都不会乱掉,总能在正确的时机显示正确的内容。

    查看详情
  • 4

    Custom Property Editors — Overview & Comparison

    第 355 页

    嗨,同学们,咱们今天来聊聊一个特别实用的话题——,自定义属性编辑器,。 你平时在 Flow Builder 里拖一个可调用动作或者屏幕组件的时候,是不是发现属性面板里都是干巴巴的文本框?所有参数全靠手打,既不方便也容易出错。自定义属性编辑器呢,就是要把这种纯文本的体验,变成一个丰富、友好的配置界面,比如下拉菜单、动态挑选列表、条件式输入,甚至带搜索的记录选择器。 那哪些地方能用上它呢?有两种场景。 第一种,是咱们用 ,@InvocableMethod, 注解注册的,可调用动作,,动作要想在 Flow 里出现,就可以配上自定义编辑器。 第二种,是,屏幕组件,,也就是 Lightning Web 组件,只要在它的 js‑meta.xml 文件里加上 `configurationEditor` 属性指向编辑器资源,Flow Builder 就能认出这个定制界面。 好,接下来就是实际开发时用到的 JavaScript 接口。这个接口会拿到五个好帮手,咱们一个个说: 1. ,inputVariables, 这是当前属性值的列表,每个值都带着名字、当前值、还有数据类型。你就把它想象成 Flow 传进来需要编辑的“试卷”,编辑器负责展示和修改它们。 2. ,builderContext, (Slide 上写的是 builderContent,但通常叫 builderContext) 它包含了 Flow 里所有可用的元素和资源,比如其他变量、资源、筛选条件等。有了它,你就能做出,动态的挑选列表,——比方说根据前面选的字段,动态显示后面的选项。 3. ,elementInfo, 它告诉你这个组件被调用时的基础信息,比如 API 名称,还有它在 Flow 里是充当动作还是屏幕。这样你的编辑器就知道自己是在哪个角色下工作了。 4. ,genericTypeMappings, 这个用来处理通用 sObject 类型分配。Flow 里经常用 T__ 或 U__ 这种占位符来表示一个不确定的 sObject,这里就能把实际的类型映射告诉 Flow。比如 T__ 对应账户,U__ 对应联系人。 5. ,validate() 函数, 这是留给你的自定义验证函数。你可以在里面写逻辑,比如检查某个值是不是填对了,如果不对就返回一个错误消息,Flow Builder 就会在保存或运行前拦截下来,提示用户修正。 有了这些输入,编辑器就可以造出漂亮的 UI。但光有界面还不行,用户改了东西得告诉 Flow Builder 呀。这就是需要,发送事件,了!Slide 里提到三种事件,都是咱们在编辑器里需要派发出去的: - ,Value_Changed, 当用户改了一个属性的值,你就派发这个事件,带上 `name`(哪个属性)、`newValue`(新的值)、还有 `newValueDataType`(新值的数据类型)。这样 Flow Builder 就会自动更新对应的变量。 - ,Value_Deleted, 如果用户清空或删除了某个属性,就发这个事件,只带 `name`,Flow Builder 就知道这个属性被重置了。 - ,generic_style_mapping_changed, 这个事件跟通用类型映射有关,当映射关系变了,你就派发它,带上 `typeName`(比如 T__)和 `typeValue`(实际的 sObject API 名),告诉 Flow Builder 类型指派已经更新。 这里有一个,非常关键的点,:无论你派发哪种事件,都一定要在事件定义里设置 `bubbles: true` 和 `composed: true`。如果不加这两个,事件就穿透不到 Flow Builder 的壳里,你的修改就传不出去,界面点了白点。 总结一下,自定义属性编辑器就像给 Flow Builder 装上了一套智能外壳,让搭建流程的人点一点、选一选就能配置复杂逻辑,既高效又不容易出错。咱们开发时,先确定是给动作还是屏幕组件用,配上编辑器入口,然后在 JS 里利用好那五个输入,最后通过三个特定事件把改动传回去,并且千万记得那个 bubbles 和 composed 的设置。 好了,今天的内容就这么多。下次动手做 Flow 组件的时候,你就可以试试把那个傻傻的文本框变成一个贴心的配置面板了!

    查看详情
  • 5

    Custom Property Editor — Invocable Action Example

    第 356 页

    好了,我们来聊聊这个知识点。在Lightning Web Components里,我们有时候需要给Flow里的操作做一个自定义的属性编辑器,就是用来配置操作的输入参数的。这个幻灯片呢,就用一个HTML电子邮件的操作作为例子,来展示全流程怎么做。 首先,在Apex类里,我们用@InvocableMethod注解的时候,通过一个配置项Editor指定一个自定义的编辑器组件。比如这里写的是Editor='c-html-email-editor',意思就是告诉Flow:“我不用默认的编辑器,要用这个叫html-email-editor的Lightning组件来让用户填参数。” 那这个编辑器组件长什么样呢?它的HTML部分是经过样式化设计的。它把输入项很清楚地分成几个逻辑区块,比如大写字体区、主题区、还有邮件正文区,这样用户一看就明白该填什么。 接着看JavaScript部分。它用getter方法,通过inputVariables数组,按名称去取出每个输入字段的值。这样在组件里就能拿到用户填的这些值了。 然后有个很关键的validate方法。Flow Builder在用户点击保存时会调用这个方法来校验输入。它负责检查电子邮件地址格式有没有问题。如果通过,返回空数组;如果出错,就返回一个包含{key, errorString}对象的数组。key是出错的字段名,errorString是提示信息。这样Flow Builder就能自动显示错误数量,提醒用户。 顺便说,每当用户在编辑器里改动了某个字段,会触发一个叫configuration_editor_input_value_changed的方法。这个方法会派发一个事件,把字段的name、新值newValue和值的数据类型newValueDataType一起送出去,这样Flow就能实时捕捉变化。 最后看一下组件的XML配置文件。它很简单,只需要写上apiVersion和isExposed就行了,连targets都不用写。为什么?因为这里不是独立使用的组件,而是通过Apex类的@InvocableMethod引用的,所以不需要暴露给更多目标类型。 这就是HTML电子邮件操作示例里,自定义属性编辑器的实现方式。你以后做类似的功能,照着这个模式来就行。

    查看详情
  • 6

    Custom Property Editor — Screen Component & Generic SObject

    第 357 页

    好的同学,今天我们来讲一讲屏幕组件自定义编辑器这块的内容。别担心,虽然一开始听起来有点复杂,但我会用最简单的话,一步一步带你走完。 首先,屏幕组件都知道吧?就是在Flow里拖出来,让用户交互的那些组件。有时候我们需要给这些组件在Flow设计器里提供一个更友好的编辑界面,好让管理员能方便地配置组件属性。这时候就需要自定义编辑器了。 那怎么让一个屏幕组件知道自己用的是哪个编辑器呢?其实很简单,就在组件的元数据配置文件里,也就是那个xml文件里,有个叫`targetConfig`的配置项,它下面可以指定一个`editor`属性,把自定义编辑器的名字填上,这就注册好了。就像告诉系统:“嘿,我这个组件,配置的时候别用你默认的样子,用我给你的那个编辑器来展示。” 好,我们来看一个典型的例子——音量滑动器组件。这个例子很经典,它展示了一个完整的编辑器长什么样。它里面有个关键的设计模式:通过一个私有字段 `_inputVariables` 来保存所有的输入变量。编辑器怎么读这些变量呢?它定义了一个 `inputVariables` 的 getter/setter。这样当Flow传值进来,它就能存到那个私有字段里。然后为了方便取某个具体值,它还会写一些专门提取属性的 getter,比如要获取最小音量,就写一个 `minVolume` 的 getter,直接从 `_inputVariables` 里把对应值找出来。 接下来是校验问题。编辑器里可能要做一些自定义校验,比如音量滑动器要检查最大值是不是大于最小值。它用了 `validate()` 方法,在这里写校验逻辑。如果发现有问题,就调用滑动器组件自带的 `setCustomValidity` 方法,这个方法能在组件上直接显示一个内联的错误提示,而不需要弹窗,非常直观。 另外,当用户在编辑器里改了配置,需要把这个变化同步出去。这里用的是 `Inbox Change` 调度事件。具体来说,当值发生变化,编辑器会触发一个叫 `_changed` 的事件,并且告诉系统这个值是 `Number` 类型。这样Flow就能收到通知,刷新预览什么的。 好,我们再来看看通用的 `sObserver` 输入怎么处理。有时候组件需要处理任意类型的对象,比如一个Record,我们不想写死具体是哪个对象类型,就要用泛型。在组件的 `.js-meta.xml` 里面,可以定义一个叫 `Property Type` 的子标签,用来声明泛型参数。比如我写一个名字叫 `T`,并且指定它要继承自 `SObject`(这里原意是 extends='SObitch’,应该是笔误,指SObject)。然后在组件的属性类型里,我们就可以用 `{T}` 来表示这个泛型。如果是一个集合,就写 `{T[]}`。这样组件的适用范围一下就大了。 那编辑器里怎么获取和设置这个泛型实际传入的类型呢?这时候就会使用 `genericTypeMappings` 接口。这个接口就像个字典,把泛型符号 `T` 映射到它真实代表的SObject类型名称。通过它,编辑器就能知道用户到底选了Lead还是Account,从而把具体的值取出来或者设进去。 最后说一下“收件箱惯例”的差异。这是一个很容易混淆的点。屏幕组件和可调用操作(比如Apex Action)在处理泛型时的命名规则不一样。屏幕组件很直白,直接用普通的属性类型名称就行了,比如刚才的 `{T}`。但是在可调用操作里,输入泛型要在前面加个特殊前缀,变成 `T__prective`,输出泛型则用 `U__prective`。这个前缀是平台自动给你加上去的,你不需要手动干预,但要知道有这回事,不然在代码里看到会很懵。所以记住:屏幕组件用原样,可调用操作加前后缀。 好了,今天的内容就到这里。我们回顾一下:编辑器注册靠 `targetConfig` 的 `editor` 属性;音量滑动器展示了典型的 getter/setter 模式、属性提取 getter、`validate` + `setCustomValidity` 内联校验,以及 `_changed` 事件调度值;通用输入通过 `Property Type` 定义泛型,用 `{T}` 或 `{T[]}` 引用,编辑器通过 `genericTypeMappings` 获取具体类型;而命名惯例上,屏幕组件不加前缀,可调用操作要加 `__prective`。好,大家消化一下,有问题随时提。

    查看详情
  • 7

    SObject Input Editors & JavaScript Interface

    第 358 页

    同学,我们来看这一页幻灯片,它讲的是在Lightning Web Components里,如何正确处理sObject数据输入以及事件的几个关键点。 首先你要记住,当我们需要把前端的sObject数据传给Apex方法,或者放到一个属性里传给父组件时,常常要用JSON.stringify把对象转成字符串。但这里一定要注意:序列化的时候,sObject必须带上type字段。也就是说,你的数据对象要像这样:{ attributes: { type: "Contact" }, LastName: "张三" }。如果你漏了type,后端就没法识别这是哪种记录。 幻灯片举了一个创建联系人的例子。它会在组件里维护一个defaultContact对象,这个对象里已经包含type字段。然后每次用户修改表单中的字段,处理程序就会更新这个对象,并且在每次修改时立即用JSON.stringify序列化整个defaultContact。这样做的好处是每一步都有完整的数据结构。 更复杂一点的情况是动态行,比如创建多个账户。幻灯片用SObject收集输入形容这个过程,你可以通过添加行和删除行的按钮来管理这些动态输入。为了保证每一行都能被框架正确追踪,要给每一行设置唯一的迭代键。然后,幻灯片提供了一个方法叫getAccountsFromSYS,它会把所有行数据映射成sBody格式。映射的时候,一定记得为每个账户对象添加type属性,比如{ attributes: { type: "Account" }, Name: "新账户" },之后再调用JSON.stringify。这样就能把整组账户一次性序列化。 接下来幻灯片提到了一个JavaScript接口摘要,这是指组件配置文件里定义的接口。组件接口会涵盖五种输入:inputVariables、builderContent、elementInfo、genericTypeMappings和validate。同时我们还要声明三种事件类型。而且幻灯片强调,所有自定义事件都必须设置bubble: true和composed: true。bubble为真事件会向上冒泡,composed为真则能穿过Shadow DOM边界,这样父组件或应用构建器才能接收到。 在处理数据类型时,接口中用newValueDataType字段来指定接收的数据类型。类型有四种:String、Number、SObject(用于一般的文本类型对象)和Reference(用于引用记录变量)。你可以根据输入变量的用途选择合适的类型。 最后,如果你要使用通用sObject编辑器,就需要用到genericTypeMappings,它允许你动态地读取或写入类型分配,让组件能处理不同种类的sObject,而不必为每种对象单独写逻辑。 总结一下,今天我们理解了几个要点:用JSON.stringify序列化sBody时必须包含type字段;动态行要用唯一键并映射出带type的格式;接口事件要设置bubble和composed为true;正确指定newValueDataType;以及通用编辑器里利用genericTypeMappings来灵活分配类型。这些细节在构建交互式组件时非常实用,一定要在练习中自己写一遍加深印象。

    查看详情
  • 8

    Supported Data Types & Form Factor Configuration

    第 359 页

    同学们,我们今天来讲两个在开发Lightning Web Components时非常实用的基础要点,一个是数据类型映射,另一个是外形配置。这些在流与你的组件交互时特别关键,我会结合例子一点点讲清楚。 首先,我们看数据类型映射表。它其实是定义了流和LWC之间完整兼容的类型集合。意思就是说,当你在流的逻辑里往你的组件传值,或者组件往回返值时,必须遵守这些类型规则,不然就会出错。 第一个要记住的是关于sObject对象。在映射里你不能只写一个泛泛的“Object”,必须注明具体的对象API名称,比如Account(就是客户)、Case(案例)。假如你传一个联系方式,就要点明是Contact对象。这样平台才知道怎么处理字段。 第二,布尔类型在映射里很灵活,可以接受多种“真”和“假”的格式。比如true或者false没问题,用字符串"true"、"false"也行,有些地方还能用1表示真,0表示假。但我们还是建议尽量用标准的true/false。 第三,遇到多选列表字段时,要把它转成逗号分隔的字符串来传递。比方说,你有个多选列表选了“选项A”和“选项B”,那么在映射里就应该写成"选项A,选项B",中间用英文逗号分开,不要加空格。这样组件就能正确解析。 最后,日期时间类型,必须严格遵循ISO 8601格式。举个具体的例子:2024年1月1日中午12点整,要写成"2024-01-01T12:00:00.000Z",带上时区标志。这一点千万注意,否则时间处理会乱掉。 现在讲完映射,我们来说外形配置。外形配置是用在targetConfigs里的supportedFormFactors标签,它可以控制你的组件在哪些设备尺寸上可见。简单理解,大屏体型对应桌面端,小屏体型对应手机端。你在声明支持的外形时,就是告诉Salesforce:“我这个组件要展示在桌面上,还是手机上,或者都显示。” 支持的页面类型有区别:应用程序页面和记录页面,这两种目标类型都支持大屏和小屏;但主页类型只支持大屏,小屏不会被显示出来。所以如果你想让组件在手机的主页上出现,那是不行的,主页只想让大屏看到。 这里有一个极其重要的规则,一定要记牢:一旦你的组件已经部署,并且在页面上被使用了,你就只能在supportedFormFactors里添加新的支持外形,而不能删除已有的。比如说,你原来声明了支持大屏和小屏,部署后,只能再添上新外形,但不能把小屏移除掉。因为如果删除,会导致那些已经配置了小屏显示的页面直接抛出错误,破坏用户体验。这是平台的一个保护机制。 因此,我们的最佳实践是:始终为每一个目标类型显式地定义supportedFormFactors,不要偷懒依赖默认值。显式写明你支持Large还是Small,这样既清晰,也避免未来更改时踩进无法删除的坑里。 好了,这两块内容就梳理到这里。希望大家在设计组件与流的交互,以及控制多设备展现时,能够把这些规则用上。下节课我们会看更多的实践案例,今天讲的要点大家多回顾一下。

    查看详情