Lightning App Builder
同学们,咱们今天这页Slide,内容非常扎实,它把整个Lightning App Builder的生态系统给咱们串起来了。你听我慢慢给你讲。 首先,你到底是怎么把一个组件,放进App Builder那个拖拽的界面里,让人能点来点去配置它的呢?这就要靠一个叫 `.js-meta.xml` 的配置文件。在这个文件里,你可以定义几个非常关键的东西。 第一个是“目标”,也就是Targets。你总得告诉Salesforce,我这个组件能放在哪儿吧?是放在一个记录详情页,就是RecordPage;还是放在一个自定义的应用页,AppPage;或者是放在主页,HomePage。这就像在说,我这个家具,到底是适合客厅、卧室还是书房。 定义了放哪儿之后,管理员或者开发者在配置这个组件时,还能填一些东西,这就是“属性”。这些属性,就写在那个配置文件里。比如一个“欢迎横幅”组件,我可以定义个属性叫“欢迎语”,让配置的人在App Builder里直接打字输入。 有时候,你这个组件是跟特定对象绑定的,比如只跟“客户”或“商机”对象相关,那你就可以在配置文件里加上“对象限制”,把它限制住。另外,为了让你的组件在App Builder的列表里长得好看,别忘了给它配一个“SVG图标”,这样别人一眼就能认出来,这都是在这个配置文件里做的。 好,组件放进页面了,但页面上的组件不能都是哑巴吧?它们得互相说话,进行“动态交互”。比如你点了一个客户列表里的名字,旁边那个客户详情组件就得马上刷新。这种组件到组件的通信,就是通过“事件”来实现的。具体怎么定义呢?就是在那个配置文件里,通过事件/模式元数据来声明,我这个组件能“广播”什么消息,或者能“接收”什么消息。 但有时候,通信的范围更广。比如一个页面里,既有LWC组件,又有老的Aura组件,甚至还有Visualforce页面,它们之间怎么聊天呢?这时候就要请出一个厉害的角色了——Lightning Message Service,简称LMS。它专门负责这种跨技术栈、跨DOM的通信。而且它的通信范围是可以配置的,你既可以让消息在整个应用里传,也可以让它在不同的标签页里传,非常灵活。 聊完通信,最后还得会走路吧?“导航服务”就是带咱们走路的向导。我们通过调用 `lightning/navigation` 这个服务,就能用代码控制页面跳转了。具体的做法,就是创建一个叫 `PageReference` 的对象,然后告诉它你要去哪儿。 你想去什么地方?用一个 `PageReference` 对象全能搞定!想去一条客户记录的详情页?可以;想去某个对象的列表视图,看看所有商机?可以;想直接跳转到某个对象的主页?可以;甚至你想跳一个普通的URL、另一个自定义的LWC组件、弹出一个模态窗口,或者导航到一个文件,统统都可以。 所以你看,这一页虽然东西多,但思路非常清晰。它给你勾勒出了一个完整的画面:从用配置文件让组件在App Builder里“安家落户”,到通过事件和消息服务让组件们“互通有无”,最后通过导航服务带用户在应用里“自由行走”。这就是整个App Builder生态系统的核心玩法。
本课程共有 6 个章节
同学们,今天我们来看一下在Lightning Web Components里,如何配置组件让它在App Builder里更好用。这部分内容其实就是教我们怎么把组件包装得既灵活又安全,让业务管理员拖拖拽拽就能用起来。 首先,咱们说说,App Builder的配置,。你定义组件时,可以用三个页面目标,每个目标都能定义自己的一些属性,还可以限制这个组件只能用在哪些对象上。比如一个记录页组件,你可以通过对象标签来限制它只能在“客户”或“机会”对象上出现,别的对象上就看不到。注意,这里不支持外部对象,只限标准或自定义对象。 接下来是,动态交互,,这只在App Page目标里生效。你可以在组件里定义事件和架构子标签,这样管理员就能在App Builder里把不同组件关联起来。比如一个组件发出事件,另一个组件响应,完全不用写代码。不过,架构支持的属性类型有限,只能是字符串、字节和布尔类型,然后你可以给属性加上标题和描述,方便管理员理解。 再聊聊,组件提示,,这其实是帮助管理员在搭建页面时有个好的体验。比如要支持响应式设计,让组件宽度能自适应成100%,还要考虑占位符状态,就是组件还没数据时显示什么样子。还有SIDS样式,这能保证你组件的样式和Salesforce原生风格统一,不会显得突兀。 然后,配置提示,这块,其实就是给组件起个友好的名字,让管理员一看就懂。再给必填属性设置一个合理的默认值,避免管理员漏填导致组件出错。选择列表的话,预设一些选项,管理员直接选就行,不用手动输入。 还有很重要的一点——,破坏性更改会被阻止,。意思就是,一旦你的组件被用在App Builder里了,你作为开发者就不能随便删掉里面的对象、页面类型,或者把属性的最小值最大值收紧。比如原来数字属性允许输入0到100,你不能突然改成0到50,因为这会破坏已经在用的配置。系统会锁住这些变更,保护已有的页面。 最后,如果你的组件想放在,控制台应用,里用,很简单,只要把isExposed设为true,使用AppPage目标就行,不用额外配置什么控制台特有的东西了。 简单总结一下,就是让组件在App Builder里既好配又安全,同时给管理员提供清晰的引导。这样你的组件就能像积木一样,被业务人员轻松搭建成强大的页面。接下来我们可以看一个具体的代码例子,来加深理解。
同学们,咱们今天来聊聊 Lightning Message Service,也就是闪电消息服务。它是 Lightning Experience 和 Experience Builder 里,让不同组件能够互相通信的一套标准机制,就像组件之间一条公共的“消息高速公路”。 首先,这条消息高速公路很包容,不仅咱们的闪电 Web 组件(LWC)能用,像 Aura、Visualforce 这样的旧技术也能用,甚至实用程序栏里的工具、Open CTI 电话集成,都可以在这条路上收发消息。 那么消息具体是在哪条“车道”上跑呢?我们需要在项目里创建一个 messageChannels 文件夹,在里面定义一个消息通道,这是一个 LightningMessageChannel 类型的元数据文件。然后在我们的 LWC 组件中,通过 `@salesforce/messageChannel` 这个导入路径,把通道引进来。通道的名字必须按 `频道名称__c` 这种格式写,注意结尾有个双下划线和小写 c,虽然看起来像自定义对象,但它真的不是,只是一个命名约定。如果你是在托管包里使用,通道名字前面还要加上你的命名空间,像这样:`命名空间__频道名称__c`。 接下来是作用域,也就是你能在多大范围内收得到消息。这里有两个选项:如果你在订阅时指定了 `APPLICATION_SCOPE`,也就是应用程序作用域,那你的组件就能从应用程序的任何一个角落收到这条消息。反过来,如果你省略作用域,也就是采用默认设置,那么消息就会被限制在“活动区域”内。什么是活动区域?就是你当前正在看的导航选项卡、控制台选项卡、子选项卡,还有始终处于活动状态的实用程序栏。记住,实用程序栏里的东西永远是活的,所以它永远属于活动区域。 要注意,这个作用域的功能只在 LWC 组件里使用 `@wire` 去获取消息上下文、然后调用订阅方法时才生效。你需要在 JavaScript 文件里用 `@wire(MessageContext)` 先拿到上下文,再配合 `subscribe` 方法来设置作用域。在 Aura 等其他地方用法会稍有不同,但在咱们这张幻灯片里,主要强调的是 LWC 中 `@wire` 与作用域的关系。 总结一下,Lightning Message Service 就是跨技术栈的通信利器,用消息通道定义规则,通过 `__c` 后缀来导入,再用作用域来控制消息的收听范围,清晰又灵活。好,这一小节我们就讲到这里。
咱们这节课来聊聊 Lightning Web Components 里组件之间怎么互相通知消息,也就是“发布-订阅”模式。你想象一下,两个组件在不直接认识的情况下,一个组件发消息,另一个组件收消息,就像广播电台和收音机。 先看发布消息这一边。你调用一个叫 `publish()` 函数,它需要三个东西: - 第一个,是当前页面的消息上下文,这个通过 `@wire(MessageContext)` 自动帮你拿到。 - 第二个,是你之前导入的那个,消息通道,引用,相当于你选定了要往哪个频道广播。 - 第三个,是你要发出去的,有效负载,,就是一个普通的 JavaScript 对象,里面装你想传的数据。 注意哦,那个用 `@wire(MessageContext)` 拿到的上下文,会自动在组件销毁时注销,你完全不用手动去清理它,非常省心。 接下来是订阅消息这一边,它要老老实实跟着组件的生命周期走: - 在 `connectedCallback` 里执行订阅。为了防止你重复订阅,框架已经帮你做了保护,即使这个回调被调用多次,也不会出问题。 - 在 `disconnectedCallback` 里一定要取消订阅,不然组件被移除了,它还在那傻等消息,就可能出内存问题。 订阅者收到消息后,拿到了那个有效负载,通常怎么用呢?一般就是顺手更新组件里的某个,反应属性,,比如 `recordId`,这样就能触发用 `@wire` 装饰器重新加载数据,界面也就跟着刷新了。 那可能你会问,如果我的组件不是继承自 `LightningElement`,而是那种 API 模块组件(比如一段纯 JS 逻辑),我还能用 `@wire(MessageContext)` 吗?答案是不能,因为 `@wire` 只能在 LWC 组件里用。那怎么发消息呢?这时候就要用 `deliverMessage()` 函数来发,订阅方则用 `releaseMessage()` 来取消,这两个函数专门给非 UI 场景准备的。 最后说说这个消息发布订阅服务(我们常叫它 MPS)能用在哪儿: - 它在 ,Flex 页面,、,移动应用程序,(而且这里只支持 LWC 和 Aura 混用)以及 ,Experience Builder, 的站点里都能正常工作。 - 但是!在 Salesforce 经典选项卡加 Visualforce 页面的组合里,或者 Experience Builder 里嵌入 Visualforce 时,它是不支持的。 - 那在这些不支持的容器里怎么办呢?你就得用老式的 ,pubsub 模块,(遗留工具)来实现了。 好了,记住这几个点,你就能灵活地在组件之间传递消息,实现更解耦的设计了。下节课我们聊聊具体的代码怎么写。
同学们,我们这节课来讲一讲 Lightning Web Components 里的导航服务,也就是如何让用户在应用中跳转到不同的页面。先记住核心概念:导航服务用 PageReference 对象来描述你要去的目的地,就像你在地图上输入一个地址一样。 要使用导航功能,第一步你得在组件里导入 NavigationMixin,然后把它混入你的组件类。这就像是安装一个导航工具包,让你的组件获得导航的能力。之后你就可以调用两个主要方法了:一个是 navigate,用来实际跳转;另一个是 generateUrl,用来生成跳转链接的 URL,而不是直接跳转。 navigate 方法接受两个参数,第一个是 pageReference,就是你要去哪儿;第二个参数叫 replace,是个布尔值,用来控制浏览器的历史记录。如果把 replace 设为 true,那么当前这个页面记录就会被替换掉,用户点后退按钮时会跳过中间的页面,不会返回到原来的地方。如果设为 false 或者不填,那就会保留历史,后退能回到上一页。 generateUrl 方法只接受一个 pageReference,它会返回一个 Promise,最终给你一个 URL 字符串。这个特别有用,因为你可以把这个 URL 当作普通链接的 href 值,这样用户就能右键打开新标签页,或者按住 Ctrl 点击打开新窗口,体验和标准的网页链接完全一样。 接下来说 PageReference 的类型,它覆盖了几乎所有的导航场景。第一种是 objectPage,用来导航到标准对象的列表页、主页或者新建记录页。比如你可以跳转到客户的列表,或者创建新客户。第二种是 recordPage,用来查看或编辑某条具体记录。第三种是 navItemPage,指向你在设置里定义的自定义选项卡。第四种是 webPage,可以跳转到任意的外部网址。第五种是 namedPage,用于一些特殊页面,比如 filePreview,文件预览页面。最后一种是 component,专门给那些通过 URL 就能直接访问的 Lightning 组件使用。 有一点要特别注意,导航服务在 Visualforce 容器里或者 Lightning Out 的环境下是不支持的,如果你在这些场景下用,导航可能不会生效。 好,我们简单总结一下:用 NavigationMixin 获得导航能力,用 PageReference 描述目标,用 navigate 跳转并可通过 replace 控制历史,用 generateUrl 生成链接以支持右键新标签,PageReference 有六种类型覆盖各种场景,并且注意不支持 Visualforce 和 Lightning Out。这样你就能轻松实现各种页面流转了。下节课我们会通过具体的代码示例来加深理解。
同学们,我们来看这一页幻灯片,它是讲在 Lightning Web Components 里怎么用查询参数来传递状态,核心就是 PageReference 的状态属性。 首先记住一个关键规矩:PageReference 对象是冻结的,也就是说你不能直接修改它。如果你要改,必须先复制一份。然后,所有的状态键都要加上命名空间前缀,默认是 "c__" ——就是字母c加两个下划线。而且,状态里的所有值都必须是字符串,不能是数字或者对象。还有特别重要的一点:千万别把密码、令牌这些敏感信息塞进 URL 的查询参数里,因为 URL 是明文的,不安全。 那我们怎么在组件里拿到这些状态呢?用 ClientPageReference 这个有线适配器。它能给你的组件提供反应式的访问,也就是说,当页面状态变化时,你的组件会自动收到新的值,不需要自己写复杂的监听逻辑。 那么什么组件能通过 URL 传递状态?就是 URL 可编址的组件。要让一个组件变成 URL 可编址,你需要实现 lightning__UrlAddressable 这个目标,并且在组件的元数据里声明标准__组件页面引用类型。注意这里的 componentName 要用 命名空间__组件名 的格式,比如如果你有个 helloWorld 组件,就写 c__helloWorld。 当有人导航到这个组件时,状态属性会被转换成查询参数,跟在 URL 后面,比如 ?c__recordId=123。在你的组件代码里,你就通过 ClientPageReference.State 来读取这个 recordId,简单又直接。 如果在控制台应用程序里使用,情况稍微特殊一点。你需要检查 IsConsoleNavigator,如果是,就用 openTab() 方法在工作区选项卡里打开组件,而不是跳到新页面。为了避免点同一个链接生成一堆重复的标签页,我们通常会在状态对象里加一个 uid 字段,比如生成一个随机字符串,这样每次导航都带上不同的 uid,系统就会认为是不同的选项卡,不会覆盖原来的。 最后要注意一个限制:Experience Builder 网站目前不支持 URL 可编址的组件,所以如果你在构建社区云站点,就不能用这种方式来传递参数。 好了,这一页的重点就是这些:状态要冻结、键名前缀、值转字符串、敏感数据不上URL,用 ClientPageReference 实时读取,URL 可编址组件的配置,控制台里用 openTab 加 uid 防重复,还有社区云不支持的坑。大家先消化一下,有问题随时提出来。
好,同学们,咱们来看看这个 Slide,它讲了几个非常实用的导航和传参技巧。 我会用最直白的方式,把这些点一个个串起来,你听完就能在脑子里形成清晰的画面。 先说,模式导航,。 你要打开一个模态窗口,不能在一个组件里蛮干,需要三个角色配合: 子组件负责“点火”——它通过自定义事件把要去的页面引用(pageRef)作为事件详情抛出去,自己不直接导航。 然后中间有个模式容器,它就像一个信使,负责把这个事件原封不动地转发出去,保持数据干净。 最后是父组件,它在那里稳稳接住事件,调用 `NavigationMixin.Navigate` 来真正执行导航。这样分工下来,组件各自职责单一,代码清爽又好维护。 接下来是,默认字段值,。 我们新建记录时,经常想预填一些字段,比如把联系人的姓名先写上。这时候要用 `encodeDefaultFieldValues` 这个方法。 你传一个普通对象,比如 { LastName: '张三', IsActive: true },它会帮你编码成一个加密的字符串。你在导航时,把这个字符串塞到 `state.defaultFieldValues` 里,目标页面就能拿到。 如果是做操作覆盖,比如你覆盖了标准的“新建”按钮,这时候页面上下文里已经有一个 `currentPageReference`。你需要用 `decodeDefaultFieldValues` 从这个引用里把编码字符串解码回来。 ,注意,,解码出来的所有值都是字符串形态,布尔值会变成 `'true'` 或 `'false'`,必须你自己显式地把它转成布尔,否则你的复选框可能不听使唤。 再讲,快速动作的两种模式,,这个记起来很简单。 一种是“无头模式”,就是它的 HTML 模板是空的,只跑 JS 逻辑,然后立刻调用导航去另一个地方,用户看不到界面,只是后台跳一下。 另一种是“屏幕模式”,会弹出我们熟悉的模态框,堆叠行为可以通过一个替换参数来控制——比如你想让新窗口替换当前窗口,只留一个,那就要用到这个参数。 最后是这个 slide 提到的,文件预览导航,,特别实用。 我们使用标准的 `__namedPage`,把 `pageName` 写成 `'filePreview'`,就能进入 Salesforce 的文件预览界面。它可以传一个 `recordId` 数组,让你一次预览多个文件;如果你想让打开时默认选中某一个文件,就加上 `selectedRecordId`。这样用户体验会很流畅。 好了,这些就是模式导航、默认值、快速动作和文件预览的核心点。记住三个组件配合的模式,编码解码时注意类型,你就能把导航玩得很溜。有什么问题随时提,我们接着聊。