自定义 Visualforce 页面的外观和输出

Visualforce 页面和组件 输出发送到浏览器进行呈现的 HTML。Visualforce 的 HTML 生成是 复杂,自动提供页面结构、内容和样式。Visualforce 还提供了多种方法来 更改 Visualforce 的默认 HTML, 替换您自己的资源,或关联其他资源,例如 CSS 样式表或 JavaScript 文件,带有页面。

设置 Visualforce 页面的样式

设置 Visualforce 的样式很容易 页面,要么模仿标准 Salesforce 页面的外观,要么使用您自己的页面 样式表或内容类型。

许多 Visualforce 组件都具有 or 属性。定义这些属性中的任何一个都允许您将 CSS 代码与 元件。自定义 CSS 代码使您能够更改组件的默认视觉样式, 包括其宽度、高度、颜色和字体。stylestyleClass

使用 Salesforce 样式

许多 Visualforce 组件 已经具有 Salesforce 中相同组件的外观,例如相关列表 在详细信息页面或部分标题中。这些组件的部分样式,包括 组件的配色方案基于显示组件的选项卡。您可以 通过将页面与 标准控制器,或者通过在 or 标记上设置属性。

tabStyle<apex:page><apex:pageBlock>

  • 当您将标准控制器与 Visualforce 页面一起使用时,您的 新页面采用 Salesforce 中关联对象的标准选项卡的样式。它也 允许您访问与关联对象关联的方法和记录。
  • 当您使用自定义控制器时,标签的属性允许您模仿 关联的 Salesforce 页面。 如果您只希望页面的某些部分类似于 Salesforce 页面,则可以使用 标记上的属性。有关示例,请参阅定义 Getter 方法。tabStyle<apex:page>tabStyle<apex:pageBlock>

扩展 Salesforce 样式 样式表

使用标签添加 页面的其他样式表。使用大多数 Visualforce 组件上可用的 or 属性将它们连接到 样式表中的样式定义。此技术允许您使用 有。

<apex:stylesheet>stylestyleClass下面的标记显示了一个非常基本的页面。该标记引用另存为静态的 CSS 样式表 名为 TestStyles 的资源,并列在“静态资源”页面上。它由标记属性中的全局变量引用。属性 的标记使用示例样式 样式表中定义的类。

<apex:stylesheet>$Resource<apex:stylesheet>valuestyleClass<apex:outputText>

<apex:page>
    <apex:stylesheet value="{!$Resource.TestStyles}"/>
    <apex:outputText value="Styled Text in a sample style class" styleClass="sample"/>
</apex:page>

这是用于此示例的样式表。

.sample {
    font-weight: bold;
}

使用 Lightning 设计系统

使用元素 将 Lightning Design System 合并到 Visualforce 页面中,并将它们与 Lightning Experience 的样式。此组件是上传 Lightning Design System 作为静态资源,并在 Visualforce 页面中使用它。

<apex:slds>

您不必将 Lightning Design System 作为静态资源上传。那 意味着您可以保持页面的语法简单,并保持在 250 MB 的静态资源之下 限制。要在 Visualforce 页面中使用 Lightning Design System 样式表,请在页面标记中的任意位置添加。<apex:slds />要在 Visualforce 页面中使用 Lightning Design System 样式表,请执行以下操作:

  1. 在页面中的任意位置添加 标记。<apex:slds />
  2. 将 or 属性设置为 。<apex:page>applyBodyTagapplyHtmlTagfalse
  3. 将类包含在任何 SLDS 样式上,或者 asset 父元素。slds-scope

警告

不要在元素中包装任何 Visualforce 标签。slds-scope

<apex:page standardController="Account" applyBodyTag="false">
    <apex:slds /> 
 
    <!-- any Visualforce component should be outside SLDS scoping element -->
    <apex:outputField value="{!Account.OwnerId}" /> 
 
    <div class="slds-scope">
    <!-- SLDS markup here -->
    </div>
</apex:page>

通常,闪电设计系统已经确定了范围。但是,如果将 or 设置为 false,则必须包含作用域类 slds-scope。在作用域类中,标记可以引用 Lightning Design System 样式和资源。applyBodyTagapplyHtmlTag

引用 Lightning Design System 中的资源,例如 SVG 图标和 图像,请使用公式函数和全局变量。URLFOR()$Asset使用以下命令 标记,例如,引用 SVG 帐户图标。

<svg aria-hidden="true" class="slds-icon">
    <use xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/standard-sprite/svg/symbols.svg#account')}"></use>
</svg>

若要使用 SVG 图标,请在标记中使用 和 添加所需的 XML 命名空间。

xmlns=”http://www.w3.org/2000/svg”xmlns:xlink=”http://www.w3.org/1999/xlink”html

注意

如果您使用的是 Salesforce 侧边栏、标题、 或内置样式表,则无法向 .仅当 、 和 设置为 时才支持 VG 图标。htmlshowHeaderstandardStylesheetssidebarfalse

以下标记显示了一个简单的帐户详细信息页面。此页面使用 Lightning 设计系统卡元素和帐户标准控制器。此页面还包括 帐户 PNG 图标。

此页面中没有任何数据,除非您使用记录 ID 加载它。闪电 Design System 不支持将数据导入 Visualforce 页面的组件,例如 as 和 .使用 Lightning 从页面访问 Salesforce 数据 设计系统,使用远程 对象、JavaScript 远程处理或 REST API。<apex:pageBlock><apex:detail>

<apex:page showHeader="false" standardStylesheets="false" sidebar="false" docType="html-5.0" standardController="Account" applyBodyTag="False" applyHtmlTag="False">
<head>
  <title>{! Account.Name }</title>
  <apex:slds /> 
</head>

<body class="slds-scope">
    <!-- MASTHEAD -->
    <p class="slds-text-heading--label slds-m-bottom--small">
      Using the Lightning Design System in Visualforce
    </p>
    <!-- / MASTHEAD -->
        
    <!-- PAGE HEADER -->
    <p class="slds-text-title_caps slds-line-height--reset">Accounts</p>
        <h1 class="slds-page-header__title slds-truncate" title="My Accounts">{! Account.Name }</h1>
        <span class="slds-icon_container slds-icon-standard-account" title="Account Standard Icon">
          <svg class="slds-icon slds-page-header__icon" aria-hidden="true">
              <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/standard-sprite/svg/symbols.svg#account')}" />
          </svg>
        </span>
          <!-- / HEADING AREA -->
      <div class="slds-col slds-no-flex slds-grid slds-align-top">
        <button class="slds-button slds-button--neutral">New Account</button>
      </div>
    <!-- / PAGE HEADER -->

    <!-- ACCOUNT DETAIL CARD -->
    <div class="slds-panel slds-grid slds-grid--vertical slds-nowrap">
      <div class="slds-form--stacked slds-grow slds-scrollable--y">

        <div class="slds-panel__section">
          <h3 class="slds-text-heading--small slds-m-bottom--medium">Account Detail</h3>
          <div class="slds-form-element slds-hint-parent slds-has-divider--bottom">
            <span class="slds-form-element__label">Name</span>
            <div class="slds-form-element__control">
              <span class="slds-form-element__static">{! Account.Name }</span>
            </div>
          </div>
          <div class="slds-form-element slds-hint-parent slds-has-divider--bottom">
            <span class="slds-form-element__label">Phone</span>
            <div class="slds-form-element__control">
              <span class="slds-form-element__static">{! Account.Phone }</span>
            </div>
          </div>
        </div>
        <div class="slds-panel__section slds-has-divider--bottom">
          <div class="slds-media">
            <div class="slds-media__body">
              <div class="slds-button-group slds-m-top--small" role="group">
                <button class="slds-button slds-button--neutral slds-grow">Edit</button>
                <button class="slds-button slds-button--neutral slds-grow">Save</button>
                 <button class="slds-button slds-button--neutral slds-grow">New Account</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- / ACCOUNT DETAIL CARD -->
</body>
</apex:page>

有关 Lightning Design System 样式的更多示例,请参阅 Salesforce Lightning Design System 参考站点,并了解 有关 Trailhead 上的闪电设计系统的更多信息。

使用 Lightning Experience 设置现有 Visualforce 页面的样式 样式表

在以下情况下,您可以控制页面是否使用 Lightning Experience 的外观设置样式 在 Lightning Experience 或 Salesforce 移动应用程序中查看该属性。

lightningStylesheets

注意

不支持该属性 在 Experience Cloud 站点中。lightningStylesheets

在 Lightning 中查看时,设置 Visualforce 页面的样式以匹配 Lightning Experience UI 体验或 Salesforce 移动应用程序,在标记中设置。在 Salesforce Classic 中查看页面时,它不会得到 Lightning Experience 样式。lightningStylesheets=”true”<apex:page>

<apex:page lightningStylesheets="true">

如果 ,则 CSS 作用域类会自动应用于 Visualforce 页面的元素。范围界定 类,以便您的内容与 Lightning Experience UI 匹配。如果将 或设置为 false,则必须手动添加范围类。lightningStylesheets=”true”slds-vf-scope<body>applyBodyTagapplyHtmlTagslds-vf-scope

这是一个标准的 Visualforce 页面 没有属性。页面 采用经典 UI 样式。lightningStylesheets

这是同一个 Visualforce 页面,带有 属性设置为 。lightningStylesheetstrue

您可以设置最常用的 Visualforce 样式 具有属性的组件。 但是,某些组件在风格上与 Lightning Experience 略有不同。例如,,某些元素使用浏览器的默认 而是样式。仍然支持不需要样式的常用 Visualforce 组件,例如 、 和 。lightningStylesheets<apex:inputFile><apex:inputField><apex:form><apex:outputText><apex:param>

包含不属于 Visualforce 组件库,将标记与代码和属性一起使用。<apex:slds/>lightningStylesheets

注意

  • 该属性不影响 自定义样式。必须更新自定义代码以匹配页面的 SLDS 样式。lightningStylesheets
  • 如果设置为 false,则 的属性将在 Lightning Experience 中覆盖和抑制, Salesforce Classic 和移动应用程序。standardStylesheets<apex:page>lightningStylesheets
  • 组件存在已知问题 从 Visualforce 页面创建 PDF 文件时。因此,不支持或调用<apex:slds>lightningStyleSheets<apex:page renderAs=”pdf”>PageReference.getContentAsPDF().

使用时,大多数 Visualforce 按钮显示为中性变体。按钮的中性样式出现以下原因: 没有选择器挂钩来可靠地确定哪些按钮必须打上品牌。将 style 属性添加到 以创建基于 您的组织品牌:lightningStylesheets=”true”.slds-vf-button_brand<apex:commandButton>

<apex:commandButton styleClass="slds-vf-button_brand" value="Refresh the Page">

注意

构建新功能时,请使用 Lightning Design System 按钮蓝图使用和实现该按钮。<apex:slds>

以下 Visualforce 组件支持该属性或不需要样式。lightningStylesheets

  • analytics:reportChart
  • apex:actionFunction
  • apex:actionPoller
  • apex:actionRegion
  • apex:actionStatus
  • apex:actionSupport
  • apex:areaSeries
  • apex:attribute
  • apex:axis
  • apex:barSeries
  • apex:canvasApp
  • apex:chart
  • apex:chartLabel
  • apex:chartTips
  • apex:column
  • apex:commandButton
  • apex:commandLink
  • apex:component
  • apex:componentBody
  • apex:composition
  • apex:dataList
  • apex:dataTable
  • apex:define
  • apex:detail
  • apex:dynamicComponent
  • apex:enhancedList
  • apex:facet
  • apex:flash
  • apex:form
  • apex:gaugeSeries
  • apex:iframe
  • apex:image
  • apex:include
  • apex:includeLightning
  • apex:includeScript
  • apex:inlineEditSupport
  • apex:input
  • apex:inputCheckbox
  • apex:inputField
  • apex:inputFile
  • apex:inputHidden
  • apex:inputSecret
  • apex:inputText
  • apex:inputTextArea
  • apex:insert
  • apex:legend
  • apex:lineSeries
  • apex:listViews
  • apex:map
  • apex:mapMarker
  • apex:message
  • apex:messages
  • apex:outputField
  • apex:outputLabel
  • apex:outputLink
  • apex:outputPanel
  • apex:outputText
  • apex:page
  • apex:pageBlock
  • apex:pageBlockButtons
  • apex:pageBlockSection
  • apex:pageBlockSectionItem
  • apex:pageBlockTable
  • apex:pageMessage
  • apex:pageMessages
  • apex:panelBar
  • apex:panelBarItem
  • apex:panelGrid
  • apex:panelGroup
  • apex:param
  • apex:pieSeries
  • apex:radarSeries
  • apex:relatedList
  • apex:remoteObjectField
  • apex:remoteObjectModel
  • apex:remoteObjects
  • apex:repeat
  • apex:scatterSeries
  • apex:scontrol
  • apex:sectionHeader
  • apex:selectCheckboxes
  • apex:selectList
  • apex:selectOption
  • apex:selectOptions
  • apex:selectRadio
  • apex:stylesheet
  • apex:tab
  • apex:tabPanel
  • apex:toolbar
  • apex:toolbarGroup
  • apex:variable
  • chatter:feed
  • chatter:feedWithFollowers
  • chatter:follow
  • chatter:newsFeed
  • flow:interview
  • site:googleAnalyticsTracking
  • site:previewAsAdmin
  • topics:widget

使用自定义样式

使用标记或静态 HTML 以包含您自己的样式表或样式。

<apex:stylesheet>对于 HTML 标记,您可以定义内联 CSS 代码,就像在常规 HTML 中一样 页。

<apex:page>
    <style type="text/css">
        p { font-weight: bold; }
    </style>

    <p>This is some strong text!</p>
</apex:page>

此示例引用定义为静态资源的样式表。首先,创建 样式表并将其作为名为 自定义CSS。

h1 { color: #f00; }
p { background-color: #eec; }
newLink { color: #f60; font-weight: bold; }

接下来,创建一个引用此静态的页面 资源。

<apex:page showHeader="false">
    <apex:stylesheet value="{!$Resource.customCSS}" />
    <h1>Testing Custom Stylesheets</h1>
    <p>This text could go on forever...<br/><br/>
       But it won't!</p>

    <apex:outputLink value="https://salesforce.com" styleClass="newLink">
        Click here to switch to www.salesforce.com
    </apex:outputLink>
</apex:page>

提示如果您未使用 Salesforce 样式,您可以通过阻止标准 Salesforce 样式表来缩小页面大小 装载。若要防止加载,请将组件上的属性设置为 假。如果您不加载 Salesforce 样式表、需要它们的组件不显示 正确。

standardStylesheets<apex:page>

<apex:page standardStylesheets="false">
    <!-- page content here -->
</apex:page>

Visualforce 组件 生成 HTML 具有传递和属性。这些属性 允许您使用自己的样式和样式类来控制 生成的 HTML。 允许您设置样式 直接在组件上,而 LETS 为在其他地方定义的样式附加类。例如,以下代码集 和 的类 应用 风格。

stylestyleClassstylestyleClass<apex:outputText>

<apex:page>

    <style type="text/css">
        .asideText { font-style: italic; }
    </style>

    <apex:outputText style="font-weight: bold;" 
        value="This text is styled directly."/>

    <apex:outputText styleClass="asideText" 
        value="This text is styled via a stylesheet class."/>

</apex:page>

若要使用 DOM ID 应用样式,请使用样式定义的 CSS 属性选择器。 请参阅定义组件的 DOM ID 的样式。如果您打算在样式表中使用图像,请使用 CSS 文件压缩图像,然后 将文件作为单个静态资源上传。例如,假设您的 CSS 文件有一个 像 以后。

body { background-image: url("images/dots.gif") }

合 整个目录和父 CSS 文件复制到单个 zip 文件中。在此示例中,zip 文件资源名称为 myStyles。

images

<apex:stylesheet value="{!URLFOR($Resource.myStyles, 'styles.css')}"/>

警告

如果样式表的值中包含空字符串,则无法将该页面呈现为 PDF。例如,样式 规则可防止包含该规则的任何页面呈现为 PDF。urlbody { background-image: url(“”); }

禁止显示 Salesforce 用户界面和 风格

默认情况下,Visualforce 页面采用相同的视觉样式和用户界面“镶边” 与 Salesforce 的其余部分一样。通过此默认样式行为,您可以创建如下所示的页面 它们直接内置于 Salesforce 中。如果您不希望页面具有 Salesforce 外观和 感觉,您可以抑制 Salesforce 页面和视觉设计的各个方面。您可以使用 组件上的以下属性。

<apex:page>

  • sidebar– 设置为 以禁止显示标准侧边栏。删除侧边栏会为您的页面提供 更宽的画布。例如,您可以在表中显示更多列。false此属性不 影响 Salesforce 的其余外观。您可以继续使用 、 等组件,以及通过 Salesforce 用户界面呈现的组件 造型。<apex:pageBlock><apex:detail><apex:inputField>
  • showHeader– 设置为 将禁止显示标准 Salesforce 页面设计。标题、选项卡和 侧边栏及其关联的样式表和 JavaScript 资源被删除, 就像在会话超时时帮助重定向的脚本一样。您已经准备好了空白页 填写您自己的用户界面。false但是,取消标准页面设计不会 禁止显示提供 Salesforce 可视化设计的所有样式表和脚本,或者 其他脚本包括该页面。添加到页面的 Visualforce 组件 继续采用 Salesforce 视觉设计。
  • standardStylesheets– 设置为 ,同时设置为 ,以隐含 包含支持 Salesforce 视觉设计的样式表。当您抑制 在标准样式表中,您的页面是无样式的,但您自己的样式表除外。falseshowHeaderfalse注意如果您不加载 Salesforce 样式表、需要它们的组件不显示 正确。如果未同时设置为 ,则将此属性设置为 不起作用。falseshowHeaderfalse

定义组件的 DOM ID 的样式

如果要应用样式,请使用样式定义的 CSS 属性选择器 属性选择器依赖于属性的定义,而不是 HTML 标记,以应用 CSS 样式。您可以在任何 Visualforce 组件上设置该值以设置其 DOM ID。但是,在呈现的 HTML 中是 通常以父母的 组件,作为 Visualforce 自动 ID 生成过程的一部分。例如,以下代码的实际 HTML 为:

ididididj_id0:myId

<apex:page>
    <apex:outputText id="myId" value="This is less fancy."/>
</apex:page>

你 CSS 应该通过使用属性来考虑这一点 选择器:

<apex:page>
    <style type="text/css">
        [id*=myId] { font-weight: bold; }
    </style>
    <apex:outputText id="myId" value="This is way fancy !"/>
</apex:page>

这 选择器匹配 ID 中任何位置包含“myId”的任何 DOM ID,因此您在 Visualforce 组件上设置的 如果您打算将其用于样式目的,则在页面上是唯一的。

使用 Salesforce 样式表中的样式

Salesforce 在整个应用程序中使用不同的样式表(.css 文件)来确保 每个选项卡都符合 Salesforce 的外观和感觉。这些样式表是自动的 包含在 Visualforce 页面上,除非您指定 标记的属性。

falseshowHeader<apex:page>

警告

Salesforce 样式表没有版本控制,外观和类名 的组件更改,恕不另行通知。Salesforce 强烈建议您使用 Visualforce 模仿 Salesforce 样式的外观而不是直接模仿的组件 引用并依赖Salesforce的样式表。

当您禁用包含 Salesforce 样式表时,只有您的自定义样式表 影响页面的样式。为了建立部分或全部的样式 与 Salesforce 外观相匹配,您可能希望查看和使用所选内容 默认样式表。以下样式表包含您可以引用的样式类。它们位于 Salesforce 实例的 /dCSS/ 目录中。

  • dStandard.css – 包含大多数样式定义 用于标准对象和选项卡。
  • allCustom.css – 包含自定义的样式定义 制表符。

重要

Salesforce 不提供更改通知或文档 的内置样式。使用风险自负。

识别用户看到的 Salesforce 样式

创建 Visualforce 页面时,了解 Salesforce 外观通常很有用 并感受用户的期望,以便呈现与其风格相匹配的页面。例如 一些用户可以选择自定义其外观。您需要设计您的 Visualforce 页面将这些差异考虑在内。

那里 是两个全局变量,可帮助您确定用户看到的样式:和 。这两个变量之间的区别在于,$User.UITheme 返回用户应该看到的外观和感觉, 而 $User.UIThemeDisplayed 实际返回用户的外观 看到。例如,用户可以拥有查看闪电网络的首选项和权限 体验外观,但如果他们使用的浏览器不支持该外观和 感觉,例如,旧版本的 Internet Explorer,$User.UIThemeDisplayed 返回不同的值。$User.UITheme$User.UIThemeDisplayed这两个变量都返回以下值之一:

  • Theme1– 过时的 Salesforce 主题
  • Theme2– Salesforce Classic 2005 用户 界面主题
  • Theme3– Salesforce Classic 2010 用户 界面主题
  • Theme4d——现代“闪电体验” Salesforce 主题
  • Theme4t– Salesforce 移动应用程序主题
  • Theme4u– Lightning 控制台主题
  • PortalDefault—Salesforce 客户门户 主题
  • Webstore—AppExchange 主题

假设开发人员对一些 CSS 样式进行了硬编码,使其类似于 Salesforce。为了 在新样式的 Visualforce 页面上保留相同的外观,开发人员需要 在多个样式表之间进行选择以处理用户的首选项。以下 示例显示了一种可能的完成方式 这:

<apex:page standardController="Account">
    <apex:variable var="newUI" value="newSkinOn" 
        rendered="{!$User.UIThemeDisplayed = 'Theme3'}">
        <apex:stylesheet value="{!URLFOR($Resource.myStyles, 'newStyles.css')}" />
    </apex:variable>
    <apex:variable var="oldUI" value="oldSkinOn" 
        rendered="{!$User.UIThemeDisplayed != 'Theme3'}">
        <apex:stylesheet value="{!URLFOR($Resource.myStyles, 'oldStyles.css')}" />
    </apex:variable>
    <!-- Continue page design -->
</apex:page>

请注意,在此示例中:

  • 使用属性,您可以“切换” 显示哪些部分。rendered
  • 由于标签没有 属性,您需要将其包装在 组件。<apex:stylesheet>rendered

即使为用户启用了新的外观,他们也可能没有正确运行 浏览器或辅助功能设置来查看它。下面是一个代码示例,它利用变量来显示 alternate 信息发送给 用户:

$User.UITheme

<apex:page showHeader="true" tabstyle="Case">
    <apex:pageMessage severity="error" rendered="{!$User.UITheme = 'Theme3' && 
                                                    $User.UIThemeDisplayed != 'Theme3'}">
    We've noticed that the new look and feel is enabled for your organization. 
    However, you can't take advantage of its brilliance. Please check with 
    your administrator for possible reasons for this impediment.
    </apex:pageMessage>
    <apex:ListViews type="Case" rendered="{!$User.UITheme = 'Theme3' && 
                                           $User.UIThemeDisplayed = 'Theme3'}"/>
</apex:page>

请注意,虽然等于 ,但不等于,因此页面不会呈现 充分发挥其潜力。

$User.UIThemeTheme3$User.UIThemeDisplayed

确定用户在 JavaScript 中看到的 Salesforce 样式

如果您在页面和应用程序中使用大量 JavaScript,请识别 Salesforce 主题 用户在 JavaScript 代码中看到的内容很重要。识别当前用户体验上下文 允许您在 JavaScript 代码中正确管理导航。

JavaScript 函数返回一个 包含以下值之一的字符串,用于标识当前用户界面主题。UITheme.getUITheme()

  • Theme1– 过时的 Salesforce 主题
  • Theme2– Salesforce Classic 2005 用户界面 主题
  • Theme3—Salesforce Classic 2010 用户界面 主题
  • Theme4d—现代“闪电体验”Salesforce 主题
  • Theme4t– Salesforce 移动应用程序主题
  • Theme4u– Lightning 控制台主题
  • PortalDefault—Salesforce 客户门户主题
  • Webstore—AppExchange 主题

返回的字符串值与 Visualforce 和全局变量返回的值相同。$User.UITheme$User.UIThemeDisplayed

以下标记检查当前用户体验上下文是否为 Lightning Experience 主题。

function isLightningDesktop() {
  return UITheme.getUITheme === "Theme4d";
}

HTML 注释和 IE 条件注释

Visualforce 删除了大多数 HTML 和 在呈现之前从页面进行 XML 注释,而不处理其内容。互联网 但是,资源管理器条件注释不会被删除,允许你包括 特定于 IE 的资源和元标记。

Visualforce 不会评估标准 HTML 注释 () 中包含的任何内容,无论注释是单行还是 多行。对于非 Internet Explorer 注释,Visualforce 编译器将 带有星号的 HTML 注释的内容。此替换使 HTML 注释 不适合在较旧的浏览器中注释掉 JavaScript 代码。<!– –>

Internet Explorer 条件注释最多 通常用于解决浏览器兼容性问题,通常使用旧版本的 即。尽管条件注释在页面上的任何地方都有效,但它们是 经常放置在页面的标签内, 它们可用于包含特定于版本的样式表或 JavaScript 兼容性“填充码”。<head>要在页面的标签中放置条件注释, 禁用标准 Salesforce header、sidebar 和 stylesheet,并添加您自己的 和 tags:

<head><head><body>

<apex:page docType="html-5.0" showHeader="false" standardStylesheets="false">
    <head>
      <!-- Base styles -->
      <apex:stylesheet value="{!URLFOR($Resource.BrowserCompatibility, 'css/style.css')}"/>
        
      <!--[if lt IE 7]>
          <script type="text/javascript" 
              src="{!URLFOR($Resource.BrowserCompatibility, 'js/obsolete-ie-shim.js')}>
          </script>
          <link rel="stylesheet" type="text/css" 
              href="{!URLFOR($Resource.BrowserCompatibility, 'css/ie-old-styles.css')}" />
      <![endif]--> 
    
      <!--[if IE 7]>
          <link rel="stylesheet" type="text/css" 
              href="{!URLFOR($Resource.BrowserCompatibility, 'css/ie7-styles.css')}" />
      <![endif]-->
    </head>

    <body>
        <h1>Browser Compatibility</h1>
        <p>It's not just a job. It's an adventure.</p>
    </body>
</apex:page>

Visualforce 不支持或 评估 Visualforce 标签,用于 示例, , 在 标准 HTML 注释。但是,它将在 IE 中计算以下表达式 条件评论:

<apex:includeScript/>

  • 全局变量,例如 和$Resource$User
  • 函数URLFOR()

请参阅 Microsoft 的 Internet 文档 Explorer 条件注释,以获取有关如何使用它们的更多详细信息。

快速开始使用 Visualforce

为了展示 Visualforce 的基本元素,本章包括一组示例: 演示语言的功能。虽然这些示例没有涉及每个细节,但规则或 例外,新的 Visualforce 开发人员可以使用本教程来 了解 Visualforce 的工作原理,然后再继续阅读 本指南的其余部分。

这些示例分为初级和高级部分。初学者的例子主要是 使用 Visualforce 标记。高级示例除了使用 Lightning Platform Apex 代码外,还使用 Visualforce 标记。

高深 需要 Apex 的示例在它们自己的章节中。

成功编译 Visualforce

您无法保存 Visualforce 页面 和组件,除非它们正确编译。以下是以下需要注意的事项 创建 Visualforce 页面:

  • 验证组件标记是否以正确的命名空间标识符开头,例如 — 即后跟冒号。apex:apex
  • 确保每个开头的引号和括号都有一个结束的引号。
  • 验证控制器或控制器扩展的名称是否正确。
  • Visualforce 页面和组件 使用 Salesforce API 版本创建 19.0 或更高版本必须编写为格式正确的 XML。通常,这意味着元素必须 正确嵌套的非空元素必须具有结束标记,空元素必须终止 带有右斜杠 (“”),依此类推。这 万维网联盟 (W3C) 提供了一篇文章 关于格式良好的 XML 的规范。/允许以下例外情况:
    • JavaScript 中允许违反格式正确的 XML 的代码。例如,你没有 需要在 Visualforce 中使用标签。<![CDATA[]]>
    • 表达式中允许使用违反格式正确的 XML 的代码。例如,您 不需要在公式中转义引号。
    • 通常在页面开头需要的 XML 指令(如 )可以 出现在顶级容器标记中,如 和 。<?xml version=”1.0″ encoding=”UTF-8″?><apex:page><apex:component>

创建您的第一个页面

启用开发模式后,您将 可以通过在浏览器中输入页面的 URL 来创建您的第一个 Visualforce 页面 地址栏作为 遵循:

https://MyDomainName.my.salesforce.com/apex/myNewPageName

例如,如果您想创建一个名为“HelloWorld”的页面和您的 Salesforce 组织使用 ,输入 http:// MyDomainName.my.salesforce.com/apex/HelloWorldMyDomainName.my.salesforce.com

由于该页面尚不存在,因此系统会将您定向到中介 页面,您可以从中创建新页面。单击创建 页面 <myNewPageName> 创建它 自然而然。

注意

如果您没有 Visualforce 启用开发模式后,您还可以通过输入“快速查找”框从“设置”中创建新页面, 然后选择 Visualforce 页面,然后单击“新建”。Visualforce Pages

Visualforce 页面始终可以 从设置的这一部分进行编辑,但要查看编辑结果,您必须 导航到页面的 URL。出于这个原因,大多数开发人员更喜欢工作 启用开发模式,以便他们可以在单个中查看和编辑页面 窗。

新的 Visualforce 页面

你现在有 包含默认文本的 Visualforce 页面。要编辑新页面,请点击 显示在底部的页面编辑器栏 的浏览器。它将展开以显示以下 Visualforce 标记:

<apex:page>
    <!-- Begin Default Content REMOVE THIS -->
    <h1>Congratulations</h1>
    This is your new Apex Page: HelloWorld
    <!-- End Default Content REMOVE THIS -->
</apex:page>

此默认标记包含任何页面唯一必需的标记 — 标记 开始和结束任何页面标记。嵌入在开始和结束标记中的是纯文本, 其中一些使用标准 HTML 标记 .<apex:page><apex:page><h1>

只要保留所需的标签,就可以添加尽可能多的纯文本或有效标签 HTML 添加到此页面。例如,在输入以下内容后 代码,然后在页面编辑器中单击“保存”, 页面以粗体显示文本“Hello World!”:<apex:page>

<apex:page>
    <b>Hello World!</b>
</apex:page>

提示

注意警告 – 如果您使用 HTML 保存页面,则 Visualforce 编辑器会显示警告 不要为每个打开的标签都包含匹配的结束标签。虽然 页面保存时,此格式错误的 HTML 可能会导致渲染出现问题 页。

使用 Visualforce 显示字段值

Visualforce 页面使用 与公式相同的表达式语言,也就是说,其中的任何内容都被计算为可以 从当前位于上下文中的记录中访问值。{! }例如,您可以 通过向页面添加表达式来显示当前用户的名字:{!$User.FirstName}

<apex:page>
    Hello {!$User.FirstName}!
</apex:page>

$User是一个全局变量,总是 表示当前用户记录。所有全局变量都使用 $ 符号引用。 有关可在 Visualforce 中使用的全局变量列表,请参阅全局变量。

访问字段 来自全球不可用的记录,例如特定客户、联系人或 自定义对象记录,您需要将页面与控制器关联。 控制器为页面提供数据和业务逻辑,这些数据和业务逻辑使应用程序成为现实 run,包括指定如何访问特定对象的记录的逻辑。 虽然您可以使用 Apex 为任何页面定义自定义控制器,但 Salesforce 包括标准 每个标准和自定义对象的控制器。

例如,要对帐户使用标准控制器,请将属性添加到标记中,并为其分配 Account 对象:standardController<apex:page>

<apex:page standardController="Account">
    Hello {!$User.FirstName}!
</apex:page>

保存页面后,页面的“帐户”选项卡将突出显示,并且 页面上组件的外观与“帐户”选项卡匹配。此外,您 现在,可以使用表达式语法访问当前在上下文中的客户记录上的字段。{!account.<fieldName>}

例如,若要在页面上显示帐户名称,请在页面标记中使用:{!account.name}

<apex:page standardController="Account">
    Hello {!$User.FirstName}!
    <p>You are viewing the {!account.name} account.</p>
</apex:page>

表达式调用 标准帐户中的方法 controller 返回当前在上下文中的帐户的记录 ID。然后它使用 dot 表示法来访问该字段 记录。

{!account.name}getAccount()name

注意

保存页面时,所有输入的属性 组件—, ,等 – 经过验证以确保 它是一个表达式,没有文字文本或空格,是一个 对单个控制器方法或对象属性的有效引用。value<apex:inputField><apex:inputText>错误 将阻止保存页面。若要将客户记录引入当前上下文,必须 向指定记录 ID 的页面 URL 添加查询参数。为此,请执行以下操作:

  1. 通过您希望的任何方式查找帐户的 ID。一种简单的方法是查看 客户记录的详细信息页面,并复制 网址。例如,如果您导航到包含以下内容的帐户详细信息页面 网址:https://MyDomainName.my.salesforce.com/001D000000IRt53然后是 帐户。001D000000IRt53
  2. 返回页面,将帐户 ID 作为查询字符串参数添加到 浏览器的地址栏。例如,如果您的页面位于 在:https://MyDomainName.my.salesforce.com/apex/HelloWorld2添加到末尾 这 网址:?id=001D000000IRt53https://MyDomainName.my.salesforce.com/apex/HelloWorld2?id=001D000000IRt53

注意

如果在 URL 中使用该参数,则必须引用 到标准控制器中引用的同一实体。id

在 URL 中指定帐户 ID 后,页面将显示相应的帐户 名称,如下图所示。

在 Visualforce 中显示帐户数据 页

使用 Visualforce 组件库

到目前为止,示例中唯一使用的 Visualforce 标记是必须放置的必需标记 在所有 Visualforce 标记的开头和结尾。但是,就像您可以将图像或表格插入 带有 or 标签的 HTML 文档, 您可以使用 Visualforce 组件库中定义的标签将用户界面组件添加到 Visualforce 页面。<apex:page><img><table>

例如,要添加一个组件,该组件看起来像 详情页面中,请使用 component 标签:<apex:pageBlock>

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!"> 
            You are viewing the {!account.name} account.
    </apex:pageBlock> 
</apex:page>

<apex:pageBlock> 组件

其他常见的 Salesforce 界面也存在标签 组件,例如相关列表、详细信息页面和输入字段。 例如,要添加详情页面的内容,请使用 component 标签:<apex:detail>

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are viewing the {!account.name} account.
    </apex:pageBlock>
    <apex:detail/> 
</apex:page>

<apex:detail> 组件不带 属性

标签上没有任何指定属性,显示完整的 上下文记录的详细信息视图。如果要修改属性 例如,显示哪些记录详细信息,或者是否相关列表 或者标题出现时,可以在标签上使用属性。例如 以下标记显示上下文帐户的 所有者,没有相关列表或彩色标题栏:<apex:detail>

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are viewing the {!account.name} account.
    </apex:pageBlock>
    <apex:detail subject="{!account.ownerId}" relatedList="false" title="false"/> 
</apex:page>

<apex:detail> 组件不带 相关列表或标题元素

如果更新或编辑了组件,则引用该组件的 Visualforce 页面也会 更新。

要浏览组件库,请单击“页面编辑器”中的“组件引用”。在此页面中,您可以向下钻取到任何组件 以查看每个属性可用的属性,包括任何自定义属性 您定义的组件。

使用 Visualforce 页面覆盖现有页面

假设您要更改现有页面的格式,例如标准帐户 详情页面。帐户的所有信息都显示在一个页面上。如果有很多 的信息,你最终可能会做很多滚动。使用 Visualforce 页面,您可以 使客户的每个部分显示在选项卡中,例如联系人、商机等 上。

首先,使用快速修复创建一个新的 Visualforce 页面。

  1. 在浏览器中,将文本 /apex/tabbedAccount 添加到 您的 Salesforce 实例。例如,如果您的 Salesforce 实例是 https:// MyDomainName.my.salesforce.com, 新 URL 将为 https:// MyDomainName.my.salesforce.com/apex/tabbedAccount。 您将收到以下错误消息:
  2. 单击“创建页面”tabbedAccount“以创建新页面。
  3. 单击页面左下角的“页面编辑器”链接。这将显示 新页面的代码,应如下所示 这:<apex:page> <!-- Begin Default Content REMOVE THIS --> <h1>Congratulations</h1> This is your new Page: tabbedAccount <!-- End Default Content REMOVE THIS --> </apex:page>
  4. 将现有代码替换为以下内容,然后单击“保存”:<apex:page standardController="Account" showHeader="true" tabStyle="account" > <style> .activeTab {background-color: #236FBD; color:white; background-image:none} .inactiveTab { background-color: lightgrey; color:black; background-image:none} </style> <apex:tabPanel switchType="client" selectedTab="tabdetails" id="AccountTabPanel" tabClass='activeTab' inactiveTabClass='inactiveTab'> <apex:tab label="Details" name="AccDetails" id="tabdetails"> <apex:detail relatedList="false" title="true"/> </apex:tab> <apex:tab label="Contacts" name="Contacts" id="tabContact"> <apex:relatedList subject="{!account}" list="contacts" /> </apex:tab> <apex:tab label="Opportunities" name="Opportunities" id="tabOpp"> <apex:relatedList subject="{!account}" list="opportunities" /> </apex:tab> <apex:tab label="Open Activities" name="OpenActivities" id="tabOpenAct"> <apex:relatedList subject="{!account}" list="OpenActivities" /> </apex:tab> <apex:tab label="Notes and Attachments" name="NotesAndAttachments" id="tabNoteAtt"> <apex:relatedList subject="{!account}" list="CombinedAttachments" /> </apex:tab> </apex:tabPanel> </apex:page>
  5. 请注意,“帐户”页面中没有数据。您需要指定 ID URL 中的特定帐户,就像您在前面的页面中所做的那样,例如 https:// MyDomainName.my.salesforce.com/apex/tabbedAccount?id=001D000000IRt53。 添加帐户 ID 后,您的页面应显示如下:

关于页面标记的注意事项:

  • <style>实际上是 CSS 标记的一部分,而不是 Visualforce 标记。它定义了两种类型的选项卡的样式:activeTab 和 inactiveTab。
  • <apex:tabPanel>用于生成 制表符。请注意它如何使用以下属性:
    • tabClassattribute:指定样式 用于在选项卡处于活动状态时显示选项卡的类。
    • inactiveTabClassattribute:指定 用于在选项卡处于非活动状态时显示选项卡的样式类。
  • 在选项卡面板的定义中,是每个子选项卡组件的定义。第一个选项卡使用标记返回该部分 的详细信息视图的 页:<apex:tab><apex:detail><apex:tab label="Details" name="AccDetails" id="tabdetails"> <apex:detail relatedList="false" title="true"/> </apex:tab>而 其余选项卡使用 指定帐户的不同部分 页。以下是联系人的选项卡。它使用现有的联系人列表。<apex:relatedList><apex:tab label="Contacts" name="Contacts" id="tabContact"> <apex:relatedList subject="{!account}" list="contacts" /> </apex:tab>

现在,您已经创建了一个页面来显示带有选项卡的帐户,您可以使用此页面来 覆盖所有帐户的详细信息视图。

  1. 从帐户的对象管理设置中,转到按钮、链接和操作。
  2. 单击“查看”旁边的“编辑”。
  3. 在“Salesforce Classic”部分中,选择“Visualforce” 页面
  4. 从“Visualforce”页面下拉列表中,选择“tabbedAccount”。
  5. 点击保存

单击“帐户”选项卡,然后选择任何帐户。现在将显示帐户的详细信息 带标签。

重定向到标准对象列表 页

对于将用户导航到标准选项卡的按钮或链接,您需要 可以重定向内容以显示标准对象列表。使用以下标记创建 Visualforce 页面:

<apex:page action="{!URLFOR($Action.Account.List, $ObjectType.Account)}"/>

用户将看到一个类似于以下内容的页面:

覆盖帐户详细信息页面Visualforce 页面还可以引用其他标准对象,例如联系人、 通过更改对标准对象的引用。例如:

<apex:page action="{!URLFOR($Action.Contact.List, $ObjectType.Contact)}"/>

在页面中使用输入组件

到目前为止,本快速入门教程中的示例展示了在 Visualforce 页面。捕获 来自用户的输入,请使用标记 具有一个或多个输入组件和 OR 标记来提交表单。<apex:form><apex:commandLink><apex:commandButton>

表单中最常使用的输入组件标记是 。此标记呈现 基于标准或自定义对象字段类型的相应输入小组件。为 例如,如果您使用标签 若要显示日期字段,表单上会显示一个日历小组件。如果您使用标签显示选择列表 字段中,则会显示一个下拉列表。该标记可用于捕获任何 标准或自定义对象字段,并遵循在该字段上设置的任何元数据 定义,例如字段是必填字段还是唯一字段,或者当前用户是否为 有权查看或编辑它。<apex:inputField><apex:inputField><apex:inputField><apex:inputField>

例如,以下页面允许用户编辑和保存帐户的名称:

注意

请记住,要使此页面显示帐户数据,有效的 ID 必须在页面的 URL 中将客户记录指定为查询参数。为 例:

https://Salesforce_instance/apex/myPage?id=001x000xxx3Jsxb
<apex:page standardController="Account">
    <apex:form> 
        <apex:pageBlock title="Hello {!$User.FirstName}!">
            You are viewing the {!account.name} account. <p/>
            Change Account Name: <p/> 
            <apex:inputField value="{!account.name}"/> <p/>
            <apex:commandButton action="{!save}" value="Save New Account Name"/> 
        </apex:pageBlock>
    </apex:form> 
</apex:page>

请注意,在示例中:

  • 标签已绑定 通过设置标签的属性添加到帐户名称字段。表达式 包含熟悉的点表示法,用于在 页。<apex:inputField>value{!account.name}
  • 标签具有属性。的值 此属性调用操作 的标准帐户控制器,其执行方式与标准帐户编辑页面上的“保存”按钮相同。<apex:commandButton>actionsave

注意

保存页面时,所有输入的属性 组件—, ,等 – 经过验证以确保 它是一个表达式,没有文字文本或空格,是一个 对单个控制器方法或对象属性的有效引用。value<apex:inputField><apex:inputText>错误 将阻止保存页面。

<apex:form> 组件具有单个 输入字段

标记无法显示的唯一字段是定义为自定义控制器类的成员变量的字段 用 Apex 写。若要收集这些变量的数据,请改用 、 、 或 标记。<apex:inputField><apex:inputCheckbox><apex:inputHidden><apex:inputSecret><apex:inputText><apex:inputTextarea>

添加和自定义输入字段标签

在组件内部使用时,Visualforce 输入组件和某些输出组件会自动显示 字段的表单标签。对于映射到标准或 自定义对象字段,显示的标签为对象字段标签 默认情况下。要覆盖默认值,并且对于 不直接映射到对象字段,您可以设置标签 使用属性 的组件。例如:<apex:pageBlockSection>label

<apex:page standardController="Contact">
    <apex:form>
        <apex:pageBlock title="Quick Edit: {!Contact.Name}">
            <apex:pageBlockSection title="Contact Details" columns="1">
                <apex:inputField value="{!Contact.Phone}"/>
                <apex:outputField value="{!Contact.MobilePhone}" 
                    label="Mobile #"/>
                <apex:inputText value="{!Contact.Email}" 
                    label="{!Contact.FirstName + '’s Email'}"/>
            </apex:pageBlockSection>
            <apex:pageBlockButtons >
                <apex:commandButton action="{!save}" value="Save"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
</apex:page>

注意

要使此页面显示联系人数据, 必须将有效联系人记录的 ID 指定为查询参数 在页面的 URL 中。例如

https://Salesforce_instance/apex/myPage?id=003D000000Q513R

该属性可能 是字符串,或者是计算结果为字符串的表达式。如果设置为空字符串,则窗体 该字段的标签将被禁止显示。labellabel

该属性可以 在以下 Visualforce 组件上设置:label

  • <apex:inputCheckbox>
  • <apex:inputField>
  • <apex:inputSecret>
  • <apex:inputText>
  • <apex:inputTextarea>
  • <apex:outputField>
  • <apex:outputText>
  • <apex:selectCheckboxes>
  • <apex:selectList>
  • <apex:selectRadio>

自定义标签和错误消息

设置后, 该属性将是 用于组件级错误消息,例如,当字段 是必需的或必须是唯一的。自定义标签不会在自定义中使用 错误消息,并将改用默认对象字段标签。 如果设置属性 设置为空字符串,默认对象字段标签将用于 所有错误消息。labellabel

设置表单中字段的 Tab 键顺序

Visualforce 表单具有 按 Tab 键浏览输入字段的“自然顺序”:从左到右、从上到下。对于某些人来说 形式,这可能不是最有效或最容易获得的安排。您可以使用页面中输入和其他组件的 and 属性来更改 Tab 键顺序到您想要的任何内容。

tabIndextabOrderHint

下面是一个简单的示例,该示例使用该属性来控制 Tab 键顺序。tabOrderHint

<apex:page standardController="Account">
    <apex:form>
    <apex:pageBlock title="Edit Account: {!Account.Name}">
        <apex:pageBlockSection title="Account Details" columns="1">
            <apex:inputField value="{!Account.Name}" tabOrderHint="4"/>
            <apex:inputField value="{!Account.Website}" tabOrderHint="3"/>
            <apex:inputField value="{!Account.Industry}" tabOrderHint="2"/>
            <apex:inputField value="{!Account.AnnualRevenue}" tabOrderHint="1"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
    </apex:form>
</apex:page>

注意

请记住,要使此页面显示帐户数据,有效的 ID 必须在页面的 URL 中将客户记录指定为查询参数。为 例:

https://Salesforce_instance/apex/myPage?id=001x000xxx3Jsxb

请注意,当您显示此页面并按 Tab 键时,活动字段在 与通常预期的顺序相反。

使用 tabIndex 和 tabOrderHint

该属性用作提示 在计算要为呈现的 HTML 元素或元素的值设置的值时。它习惯于 指示与其他字段相比选择字段的相对顺序 页面组件。此值必须是介于 1 和 3276 之间的整数或表达式 其计算结果为相同范围内的整数值。Tab 键顺序以 组件 1 是用户按 TAB 键时选择的第一个组件。tabOrderHinttabindex

该属性用于直接 设置呈现的 HTML 的值 元素。它是一个绝对索引,用于设置字段的顺序 选择,与其他页面组件相比。此值必须是介于 0 之间的整数 和 32767,或计算结果为相同范围内的整数值的表达式。 Tab 键顺序以组件 0 开始,该组件是用户选择的第一个组件 按 TAB 键。tabIndextabindex该属性在 只有组件。该属性可以在 遵循 Visualforce 组件。

tabOrderHint<apex:inputField>tabIndex

  • <apex:commandButton>
  • <apex:commandLink>
  • <apex:inputCheckbox>
  • <apex:inputFile>
  • <apex:inputSecret>
  • <apex:inputText>
  • <apex:inputTextarea>
  • <apex:outputLabel>
  • <apex:outputLink>
  • <apex:selectCheckboxes>
  • <apex:selectList>
  • <apex:selectRadio>

与混合时 使用该属性的组件 要设置 Tab 键顺序,您可以将 乘以 10 以获得该字段的近似等效值。使用它来 手动计算等效值,以在每个 组件,以便为 页。<apex:inputField>tabIndextabOrderHinttabIndex

向页面添加相关字段

从属字段提供了一种筛选 Visualforce 上显示的字段值的方法 页。从属字段由两部分组成:一个控制字段,用于确定 筛选,以及筛选其值的依赖字段。从属字段可以 动态筛选选择列表、多选选择列表、单选等字段中的值 按钮和复选框。从属选择列表只能显示在 Visualforce 页面上 使用 Salesforce API 版本 19.0 或更高版本。在此示例中,我们将向 Visualforce 页面添加一个依赖选择列表“子类别”。首先,创建 此自定义选择列表:

  1. 从帐户的对象管理设置中,转到字段区域,然后 ,然后单击新建
  2. 选择“选择列表”,然后单击“下一步”。
  3. 为字段输入 标签Subcategories
  4. 为值列表输入以下术语:
    • 苹果农场
    • 电缆
    • 玉米田
    • 互联网
    • 收音机
    • 电视
    • 葡萄酒酿造厂
  5. 单击“下一步”两次,然后单击“保存”。

要定义子类别的字段依赖关系,请执行以下操作:

  1. 从帐户的对象管理设置中,转到字段区域。
  2. 单击字段依赖关系
  3. 单击“新建”。
  4. 选择“行业”作为控制字段,选择“子类别”作为从属字段 田。
  5. 点击继续
  6. 成本控制字段中的每个值(来自“行业”)都列在第一行中,并且 从属字段(来自子类别)中的每个值都显示在列中 在它下面。设置字段依赖项以匹配此图像:子类别的字段依赖关系矩阵您可以忽略未显示的任何其他行业类型 以上。
  7. 点击保存

现在,创建一个 Visualforce 页面 称为看起来像 这:

dependentPicklists

<apex:page standardController="Account">
    <apex:form >
        <apex:pageBlock mode="edit">
            <apex:pageBlockButtons >
                <apex:commandButton action="{!save}" value="Save"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Dependent Picklists" columns="2">
            <apex:inputField value="{!account.industry}"/>
            <apex:inputField value="{!account.subcategories__c}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

什么时候 从“行业”选项列表中选择“农业”,子类别选项列表包含 苹果农场、玉米田和酿酒厂。如果选择“通信”,则“子类别” 选择列表包含之前定义的所有通信类型。

从属选择列表注意事项

使用依赖选择列表时,请考虑以下事项 在 Visualforce 页面中:

  • 您可以在各种字段类型中混合使用控制字段和从属字段, 例如选择列表、多选择列表、单选按钮和复选框。
  • 每页限制为 10 个依赖选择列表对。这是 在所有对象中合计。因此,您可以有五个依赖选择列表 在帐户上,在联系人上五个,但仅此而已。但是,您可以重复 同一对依赖选择列表,例如在迭代标签中,例如 ,而不计算更多 比一次违反你的极限。<apex:repeat>
  • 页面必须包含 从属选择列表的控制字段。未能包括 页面上的 control 字段导致运行时错误,当页面 显示。注意如果使用的 API 版本为 26.0 或更低版本,并且用户查看 页面对控制字段(从属 选择列表显示选择列表的所有可能值,而不是 已根据只读值进行筛选。这是 视觉力。
  • 不要混合内联 启用编辑的字段,具有来自同一依赖项的常规输入字段 群。例如,不要将标准输入字段混用 使用启用内联编辑的从属关系控制字段 田:<apex:page standardController="Account"> <apex:form> <!-- Don't mix a standard input field... --> <apex:inputField value="{!account.Controlling__c}"/> <apex:outputField value="{!account.Dependent__c}"> <!-- ...with an inline-edit enabled dependent field --> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> </apex:form> </apex:page>
  • 如果以内联方式组合 启用编辑的依赖选择列表,具有 Ajax 样式的部分页面刷新, 刷新所有字段,每个字段具有从属关系或控制关系 其他作为一个组。单独刷新字段不是 建议,并可能导致不一致的撤消/重做行为。 下面是部分刷新 具有启用内联编辑的从属表单 选择列表:<apex:form> <!-- other form elements ... --> <apex:outputPanel id="locationPicker"> <apex:outputField value="{!Location.country}"> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> <apex:outputField value="{!Location.state}"> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> <apex:outputField value="{!Location.city}"> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> </apex:outputPanel> <!-- ... --> <apex:commandButton value="Refresh Picklists" reRender="locationPicker" /> </apex:form>都 的内联启用编辑的选择列表包装在组件中。当操作方法触发时重新呈现。<apex:outputPanel><apex:outputPanel><apex:commandButton>

创建 Visualforce Dashboard 组件

Visualforce 页面可用作仪表板组件。仪表板显示源报表中的数据 作为可视化组件,可以是图表、仪表、表格、指标或 Visualforce 页面。 这些组件提供了关键指标的快照和 组织的绩效指标。 每个仪表板最多可以有 20 个组件。

使用标准控制器的 Visualforce 页面不能 在仪表板中使用。要包含在仪表板中,Visualforce 页面必须没有控制器,使用自定义 控制器,或引用绑定到 StandardSetController 类的页面。如果 Visualforce 页面不满足这些要求,则它不会显示为 仪表板组件 Visualforce Page 下拉列表中的选项。创建一个名为 的 Visualforce 页面。以下标记显示了一个 Visualforce 页面示例,该页面使用标准列表控制器,可在 仪表板。它显示与您的 组织:

VFDashboard

<apex:page standardController="Case" recordSetvar="cases">
    <apex:pageBlock>
        <apex:form id="theForm">
            <apex:panelGrid columns="2">
                <apex:outputLabel value="View:"/>
                <apex:selectList value="{!filterId}" size="1">
                    <apex:actionSupport event="onchange" rerender="list"/>
                    <apex:selectOptions value="{!listviewoptions}"/>
                </apex:selectList>
            </apex:panelGrid>
            <apex:pageBlockSection>
                <apex:dataList var="c" value="{!cases}" id="list">
                {!c.subject}
                </apex:dataList>
            </apex:pageBlockSection>
        </apex:form>
    </apex:pageBlock>
</apex:page>

要创建使用此 Visualforce 页面的仪表板,请执行以下操作:

  1. 查看仪表板,然后单击编辑
  2. 单击任意顶部的 Add Component 列。
  3. 选择 Visualforce 页面作为组件类型。
  4. (可选)输入要显示在仪表板顶部的标题 元件。
  5. (可选)输入要在仪表板底部显示的页脚 元件。
  6. 从“Visualforce 页面”下拉列表中,选择 。VFDash
  7. 点击保存

在仪表板中运行的示例 Visualforce 页面

对于使用自定义列表控制器的更复杂示例, 请参见高级 Visualforce 仪表板组件。

显示自定义对象的相关列表

重要

在可能的情况下,我们更改了非包容性条款,以符合我们的 平等的公司价值观。我们保留了某些条款,以避免对 客户实施。

使用 Visualforce 显示自定义对象及其相关列表非常简单。

假设您有三个自定义对象:MyChildObject、MyMasterObject、 和 MyLookupObject。MyChildObject 具有主从关系 替换为 MyMasterObject(即主对象)。MyLookupObject 还具有 与 MyChildObject 的 Lookup 关系。如果要创建显示 MyMasterObject 相关列表的 Visualforce 页面,请使用 以下标记:

<apex:page standardController="MyMasterObject__c">
	<apex:relatedList list="MyChildObjects__r" />
</apex:page>

要使此页面显示相关列表数据,有效的自定义对象记录的 ID 带有 自定义关系必须指定为页面 URL 中的查询参数,例如 http:// MyDomainName.my.salesforce.com/myCustomRelatedList?id=a00x00000003ij0。尽管 MyLookupObject 使用不同类型的关系, 语法相同:

<apex:page standardController="MyLookupObject__c">
	<apex:relatedList list="MyChildObjects__r" />
</apex:page>

启用内联编辑

Visualforce 页面 21.0 及更高版本支持内联编辑。内联编辑允许用户 直接在记录的详细信息页面上快速编辑字段值。可编辑单元格 将鼠标悬停在单元格上时显示铅笔图标 (可编辑字段),而不可编辑的单元格 显示锁定图标 (不可编辑的字段)。

该组件具有属性 激活内联编辑,而组件提供内联编辑 多个容器组件的功能。<apex:detail><apex:inlineEditSupport>若要查看内联编辑的强大功能,请使用以下内容创建一个名为 法典:

inlineDetail

<apex:page standardController="Account">
    <apex:detail subject="{!account.Id}" relatedList="false" /> 
</apex:page>

注意

请记住,要使此页面显示帐户数据, 必须在 URL 中将有效客户记录的 ID 指定为查询参数 用于页面。例如:

https://Salesforce_instance/apex/myPage?id=001x000xxx3Jsxb

尝试双击其中一个字段,例如“帐户” 数字。您会注意到什么也没发生。现在,将该页面替换为以下内容 法典:

<apex:page standardController="Account">
        <apex:detail subject="{!account.Id}" relatedList="false" inlineEdit="true"/> 
</apex:page>

将鼠标悬停在任何字段上,您会注意到 您现在可以直接编辑它们的内容。单击保存 该部分的顶部会保留您更改的所有信息。支持组件 内联编辑必须始终是标记的后代。但是,该组件不必是 的后代即可支持内联 编辑。

<apex:form><apex:detail><apex:form>组件必须 以下组件的后代:

<apex:inlineEditSupport>

  • <apex:dataList>
  • <apex:dataTable>
  • <apex:form>
  • <apex:outputField>
  • <apex:pageBlock>
  • <apex:pageBlockSection>
  • <apex:pageBlockTable>
  • <apex:repeat>

以下示例演示了如何使用内联创建页面 编辑:

<apex:pageBlockTable>

<apex:page standardController="Account" recordSetVar="records" id="thePage"> 
    <apex:form id="theForm"> 
        <apex:pageBlock id="thePageBlock"> 
            <apex:pageBlockTable value="{!records}" var="record" id="thePageBlockTable"> 
                <apex:column >
                    <apex:outputField value="{!record.Name}" id="AccountNameDOM" /> 
                    <apex:facet name="header">Name</apex:facet>
                </apex:column>
                <apex:column >
                    <apex:outputField value="{!record.Type}" id="AccountTypeDOM" /> 
                    <apex:facet name="header">Type</apex:facet>
                </apex:column>
                <apex:column >
                    <apex:outputField value="{!record.Industry}" 
                        id="AccountIndustryDOM" />  
                        <apex:facet name="header">Industry</apex:facet>
                </apex:column>
                <apex:inlineEditSupport event="ondblClick" 
                        showOnEdit="saveButton,cancelButton" hideOnEdit="editButton" /> 
            </apex:pageBlockTable> 
            <apex:pageBlockButtons > 
                <apex:commandButton value="Edit" action="{!save}" id="editButton" />
                <apex:commandButton value="Save" action="{!save}" id="saveButton" />
                <apex:commandButton value="Cancel" action="{!cancel}" id="cancelButton" />
            </apex:pageBlockButtons> 
        </apex:pageBlock> 
    </apex:form>
</apex:page>

以下是不支持内联编辑的情况。

  • 内联编辑在以下国家不可用:
    • 辅助功能模式
    • 设置页面
    • 仪表 板
    • 客户门户
    • HTML 解决方案的说明
  • 案例和潜在顾客编辑页面上的以下标准复选框不可内联编辑:
    • 案例分配(使用活动分配进行分配 规则)
    • 案例电子邮件通知(将通知电子邮件发送至 联系)
    • 潜在顾客分配(使用活动分配进行分配 统治)
  • 以下标准对象中的字段不可内联编辑。
    • “单据”和“价目表”中的所有字段
    • “任务”中除“主题”和“注释”之外的所有字段
    • 事件中除“主题”、“描述”和“位置”之外的所有字段
    • “个人客户”、“联系人”和“潜在顾客”的全名字段。然而,他们的 例如,组件字段为“名字”和“姓氏”。
  • 您可以使用内联编辑来更改记录上的字段值,您 具有只读访问权限,通过字段级安全性或组织的 共享模式;但是,Salesforce 不允许您保存更改,并显示 尝试保存记录时出现权限不足错误消息。
  • 标准富文本区域 (RTA) 字段不支持内联编辑,例如 as ,当 Visualforce 页面 从单独的域(Salesforce 域除外)提供服务。默认情况下, Visualforce 页面从单独的域提供,除非您的管理员有 禁用此设置。自定义 RTA 字段不受此限制的影响 并支持内联编辑。Idea.Body<apex:outputField>
  • 使用 的依赖选择列表支持内联编辑。<apex:outputField>
  • 页面必须包含从属选择列表的控制字段。未能 在页面上包含控制字段会导致运行时错误,当页面 显示。
  • 不要将支持内联编辑的字段与来自同一字段的常规输入字段混合使用 依赖项组。例如,不要将标准输入字段混用 使用启用内联编辑的从属关系控制字段 田:<apex:page standardController="Account"> <apex:form> <!-- Don't mix a standard input field... --> <apex:inputField value="{!account.Controlling__c}"/> <apex:outputField value="{!account.Dependent__c}"> <!-- ...with an inline-edit enabled dependent field --> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> </apex:form> </apex:page>
  • 如果将启用内联编辑的依赖选择列表与 Ajax 样式的部分页面结合使用 刷新,刷新所有字段,每个字段具有依赖关系或控制关系 其他作为一个组。不建议单独刷新字段,并且 可能会导致不一致的撤消/重做行为。下面是一个 部分刷新启用了内联编辑的从属表单的推荐方法 选择列表:<apex:form> <!-- other form elements ... --> <apex:outputPanel id="locationPicker"> <apex:outputField value="{!Location.country}"> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> <apex:outputField value="{!Location.state}"> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> <apex:outputField value="{!Location.city}"> <apex:inlineEditSupport event="ondblClick" /> </apex:outputField> </apex:outputPanel> <!-- ... --> <apex:commandButton value="Refresh Picklists" reRender="locationPicker" /> </apex:form>所有启用内联编辑的选项列表都包装在组件中。重新呈现时操作方法 火灾。<apex:outputPanel><apex:outputPanel><apex:commandButton>

将页面转换为 PDF 文件

您可以将任何页面呈现为 PDF,方法是将属性添加到组件,并指定 “pdf”作为渲染服务。例如:

renderAs<apex:page>

<apex:page renderAs="pdf">

呈现为 PDF 的 Visualforce 页面将显示在浏览器中或下载 作为 PDF 文件,具体取决于您的浏览器设置。

在上一教程中,您使用 Visualforce 页面更改了公司名称。假设你想生成 以 PDF 格式发布新名称。以下示例生成 这样的页面,以及当前日期和时间。

<apex:page standardController="Account" renderAs="pdf" applyBodyTag="false">
    <head>
        <style> 
            body { font-family: 'Arial Unicode MS'; }
            .companyName { font: bold 30px; color: red; }  
        </style>
    </head>
    <body>
        <center>
        <h1>New Account Name!</h1>
     
        <apex:panelGrid columns="1" width="100%">
            <apex:outputText value="{!account.Name}" styleClass="companyName"/>
            <apex:outputText value="{!NOW()}"></apex:outputText>
        </apex:panelGrid>
        </center>
    </body>
</apex:page>

关于页面的注意事项:

  • <style>是 CSS 标记, 不是 Visualforce 标记。它定义了用于整个页面的字体系列, 以及公司名称的特定样式。
  • 某些输出文本包含在组件中。一个 面板网格呈现为 HTML 表格。在身体中发现的每个组件 的组件被放入第一行的相应单元格中,直到 已达到列数。由于只有一个单元格, 每个输出文本都显示在单独的行中。<apex:panelGrid><apex:panelGrid>

呈现为 PDF 的 Visualforce 页面

在部署之前,请始终验证呈现页面的格式 它。

在页面中构建数据表

某些 Visualforce 组件(如 或 )允许您显示信息 通过遍历记录集合,一次从多个记录中获取。举例说明 这个概念,以下页面使用该组件列出与 当前处于上下文中的帐户:<apex:pageBlockTable><apex:dataTable><apex:pageBlockTable>

<apex:page standardController="Account">
   <apex:pageBlock title="Hello {!$User.FirstName}!">
      You are viewing the {!account.name} account.
   </apex:pageBlock>
   <apex:pageBlock title="Contacts">
      <apex:pageBlockTable value="{!account.Contacts}" var="contact">
         <apex:column value="{!contact.Name}"/>
         <apex:column value="{!contact.MailingCity}"/>
         <apex:column value="{!contact.Phone}"/>
      </apex:pageBlockTable>
   </apex:pageBlock>
</apex:page>

注意

请记住,要使此页面显示帐户数据,有效的 ID 必须在页面的 URL 中将客户记录指定为查询参数。为 例:

https://Salesforce_instance/apex/myPage?id=001x000xxx3Jsxb

<apex:pageBlockTable> 组件与其他迭代组件一样,包括两个必需的属性,以及:

<apex:pageBlockTable>valuevar

  • value获取 sObject 记录列表或 任何其他 Apex 类型的值。在上面的示例中,检索当前位于 上下文,然后遍历关系以检索关联的列表 接触。{!account.Contacts}
  • var指定小版本的名称 变量。此变量在标记正文中用于访问字段 在每个触点上。在此示例中,用于标记以显示联系人的姓名。<apex:pageBlockTable>value=”{!contact.Name}”<apex:column>

该组件需要 1 或更多子组件。这 表中的行数由随属性返回的记录数控制。<apex:pageBlockTable><apex:column>value

注意

组件 自动采用标准 Salesforce 列表的样式。显示列表 使用您自己的样式,请改用。<apex:pageBlockTable><apex:dataTable>

编辑页面中的数据表

在上一教程中,您构建了一个数据表。在数据中使用 表列,您可以创建具有可编辑字段的表。使用您可以保存 您更改的数据。任何消息(如 )都会自动与标记一起显示。<apex:inputField><apex:commandButton>Saving<apex:pageMessages>以下页面将创建一个页面,用于编辑系列 同时的行业类型:

<apex:page standardController="Account" recordSetVar="accounts" 
   tabstyle="account" sidebar="false">
   <apex:form> 
   <apex:pageBlock >
   <apex:pageMessages />
   <apex:pageBlockButtons>
      <apex:commandButton value="Save" action="{!save}"/>
   </apex:pageBlockButtons>

   <apex:pageBlockTable value="{!accounts}" var="a">
      <apex:column value="{!a.name}"/>
      
      <apex:column headerValue="Industry">
         <apex:inputField value="{!a.Industry}"/>
      </apex:column>

   </apex:pageBlockTable>
   </apex:pageBlock>
   </apex:form>
</apex:page>

注意

如果 URL 中具有 ID 属性,则此页面无法正确显示。例如,产生错误。您需要从 URL 中删除 ID。https://MyDomainNamePackageName.vf.force.com/apex/HelloWorld?id=001D000000IR35T请注意有关页面标记的以下事项:

  • 此页面利用标准集控制器来生成 表的数据。使用该属性指定要使用的数据集的名称。 然后,在该值中,使用该集的名称用数据填充表。recordSetVar<apex:pageBlockTable>
  • 标签会自动为字段生成正确的显示。在 这种情况,作为下拉列表。<apex:inputField>
  • 页面必须包含在标记中才能使用该标记。表单 指定用户可以与之交互的 Visualforce 页面的一部分。<apex:form><apex:commandButton>

编辑数据表的示例

在页面中使用查询字符串参数

如前面的示例所示,默认页面上下文 – 是,提供 page – 由页面 URL 中指定的查询字符串参数控制。您还可以 在 Visualforce 标记中获取和设置查询字符串参数。以下主题提供了示例:

id

  • 获取查询字符串参数
  • 在链接中设置查询字符串参数
  • 获取和设置查询字符串参数 在单个页面上

获取查询字符串参数

您可以使用全局变量在 Visualforce 标记中引用查询字符串参数。使用 ,您可以通过指定 来访问页面的查询字符串参数 属性, 之后,您可以访问每个单独的参数:$CurrentPage$CurrentPageparameters

$CurrentPage.parameters.parameter_name

例如,假设您要添加有关 “帐户”页面的特定联系人。指定客户记录 ID 按默认查询字符串 参数,联系人记录 ID 由查询字符串指定 参数命名:idcid

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying values from the {!account.name} account and a separate contact
        that is specified by a query string parameter.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" border="1">
              <apex:column>
               <apex:facet name="header">Name</apex:facet>
                {!contact.Name}
              </apex:column>
              <apex:column>
               <apex:facet name="header">Phone</apex:facet>
              {!contact.Phone}
              </apex:column>
        </apex:dataTable>
    </apex:pageBlock>
    <apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" title="false"/> 
</apex:page>

要使此示例正确呈现,您必须将 Visualforce 页面与 URL 中的有效客户和联系人 ID 相关联。例如 if 是帐户 ID 和 联系人 ID,则生成的 URL 应为:

001D000000IRt53003D000000Q0bIE

https://Salesforce_instance/apex/MyFirstPage?id=001D000000IRt53&cid=003D000000Q0bIE

使用 Visualforce 显示字段值提供了有关检索记录 ID 的更多信息。

注意

如果在 URL 中使用该参数,则必须引用 到标准控制器中引用的同一实体。id

使用查询 页面中的字符串参数

在链接中设置查询字符串参数

您可以通过构造 链接 URL,或在标签中使用标签。例如 以下两个示例都创建指向外部的相同链接 页:<apex:param><apex:outputLink>

<apex:outputLink value="http://google.com/search?q={!account.name}">
    Search Google
</apex:outputLink>
<apex:outputLink value="http://google.com/search">
    Search Google
    <apex:param name="q" value="{!account.name}"/>
</apex:outputLink>

后一种方法使用标记而不是手动创建 URL,更适合风格 原因。<apex:param>

注意

除了 ,用于 设置 和 的请求参数。<apex:outputLink><apex:param><apex:commandLink><apex:actionFunction>

获取和设置查询字符串参数 在单个页面上

看过获取和设置查询字符串参数的示例后, 此示例演示如何将这两个操作组合在一起 在单个页面上产生更有趣的结果。 根据获取查询字符串参数中的示例,以下页面将列出列表中每个联系人的名称 控制详细信息组件上下文的超链接 在它下面。这可以通过以下方式实现:

  • 将数据表包装在标签中<apex:form>
  • 将每个联系人姓名转换为适当设置参数的 标签<apex:commandLink>cid<apex:param>

当与标准控制器一起使用时,命令链接始终完全 使用添加的新信息刷新当前页面 到页面 – 在本例中,更新联系人详细信息 元件。cid

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying contacts from the {!account.name} account. 
        Click a contact's name to view his or her details.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" 
                               border="1">
              <apex:column>
               <apex:facet name="header">Name</apex:facet>
               <apex:commandLink>
                 {!contact.Name}
                 <apex:param name="cid" value="{!contact.id}"/>
               </apex:commandLink> 
              </apex:column>
              <apex:column>
               <apex:facet name="header">Phone</apex:facet>
               {!contact.Phone}
              </apex:column>
            </apex:dataTable>
        </apex:form>
    </apex:pageBlock>
    <apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" title="false"/>
</apex:page>

保存此标记后,使用查询字符串参数刷新浏览器 但没有参数 在 URL 中,例如,

idcid

https://Salesforce_instance/apex/MyFirstPage?id=001D000000IRt53

最初 不会呈现联系人详细信息页面,但当您单击联系人时 命名页面呈现相应的详细信息视图。

注意

如果在 URL 中使用该参数,则必须引用 到标准控制器中引用的同一实体。id

在页面中使用 Ajax

某些 Visualforce 组件可识别 Ajax,并允许您添加 Ajax 行为 到页面,而无需编写任何 JavaScript。以下主题 举例说明:

  • 实现部分页面更新 命令链接和按钮
  • 为异步操作提供状态
  • 将 Ajax 行为应用于任何事件 元件

实现部分页面更新 命令链接和按钮

使用最广泛的 Ajax 行为之一是部分页面 update,其中仅更新页面的特定部分 遵循某些用户操作,而不是重新加载整个页面。

实现部分页面更新的最简单方法是使用 or 标记上的属性来标识 应刷新的组件。当用户单击按钮时 或链接,仅标识的组件及其所有子组件 焕然一新。reRender<apex:commandLink><apex:commandButton>例如,请考虑获取和设置查询字符串参数中显示的联系人列表示例 在单个页面上。在该示例中,当用户单击联系人的姓名时 在列表中查看该联系人的详细信息,整个页面 由于此操作而刷新。只需进行两次修改 对于该标记,我们可以更改页面的行为,以便仅 列表下方的区域将刷新:

  1. 首先,创建或确定页面中应该 被重新渲染。为此,请将标签包装在标签中,并为输出面板指定一个参数。的值是我们可以在其他地方使用的名称 在页面中引用此区域。它在页面中必须是唯一的。<apex:detail><apex:outputPanel>idid
  2. 接下来,指示调用点(命令链接) 我们想用它来执行我们 刚刚定义。为此,请向标记添加一个属性,并为其指定分配给输出的相同值 面板的 .reRender<apex:commandLink>id

最终标记如下所示:

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying contacts from the {!account.name} account. 
        Click a contact's name to view his or her details.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" 
                               border="1">
                  <apex:column>
                      <apex:commandLink rerender="detail"> 
                          {!contact.Name}
                          <apex:param name="cid" value="{!contact.id}"/>
                      </apex:commandLink>
                  </apex:column>
            </apex:dataTable>
        </apex:form>
    </apex:pageBlock>
    <apex:outputPanel id="detail"> 
        <apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" 
                        title="false"/>
    </apex:outputPanel> 
</apex:page>

保存页面后,单击任何联系人并注意详细信息 组件在不完全刷新页面的情况下显示。

注意

不能使用该属性更新表中的内容。reRender

为异步操作提供状态

Ajax 行为(如部分页面更新)是异步的 页面用户继续在后台发生的事件 工作。为了获得良好的可用性,设计人员通常会在 提醒用户当前正在进行的任何后台活动。

Visualforce 支持使用标记进行状态更新。此标签允许您显示 带有 or 属性的后台事件开头或结尾的文本,或者,更多 高级开发人员,允许您显示图像或其他组件。<apex:actionStatus>startTextstopText

在此示例中,我们将向联系人列表页面添加状态文本 我们一直在发展。用户单击联系人姓名后, 详细信息区域显示文本“正在请求…”而 将呈现细节区域。

要实现消息,请环绕组件,因为 这是异步更新的组件。在两者之间 两个标签,添加一个名为“stop”的标签。<apex:actionStatus><apex:detail><apex:facet>分面由区域中的内容组成 提供有关数据的上下文信息的 Visualforce 组件 这在组件中呈现。例如,支持分面 用于表格的页眉、页脚和标题,而仅支持 facet 用于列的页眉和页脚。该组件允许 您可以使用自己的内容覆盖 Visualforce 组件上的默认分面。分面只允许一个子项 在开始和结束标记中。

<apex:dataTable><apex:column><apex:facet>

注意

并非所有组件 支持分面。这些列在标准组件参考中。

在以下示例中,支持包含组件的名为“stop”的分面 该操作完成后应立即显示 – 在 本例中,详情区:<apex:actionStatus>

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying contacts from the {!account.name} account. 
        Click a contact's name to view his or her details.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" 
                               border="1">
                  <apex:column>
                      <apex:commandLink rerender="detail">
                          {!contact.Name}
                          <apex:param name="cid" value="{!contact.id}"/>
                      </apex:commandLink>
                  </apex:column>
            </apex:dataTable>
        </apex:form>
    </apex:pageBlock>
    <apex:outputPanel id="detail">
        <apex:actionStatus startText="Requesting...">
            <apex:facet name="stop"> 
                <apex:detail subject="{!$CurrentPage.parameters.cid}" 
                             relatedList="false" title="false"/>
            </apex:facet>
        </apex:actionStatus> 
    </apex:outputPanel>
</apex:page>

请记住,当您访问此页面时,要将 ID 作为 URL。例如

https://Salesforce_instance/apex/ajaxAsyncStatus?id=001x000xxx3Jsxb

将 Ajax 行为应用于任何事件 元件

使用命令链接和按钮实现部分页面更新相对简单, 但是,假设您只想通过将鼠标悬停在上方来进行相同的页面更新 联系人的姓名?若要使用联系人列表示例执行此操作,请从数据表中删除标记并将联系人姓名括在 标签。在 在此输出面板中,添加一个元素作为联系人姓名的同级元素:

<apex:commandLink><apex:outputPanel><apex:actionSupport>

  • 标签定义 我们想要专门行为的区域。<apex:outputPanel>
  • 标签定义 以前由命令链接实现的部分页面更新行为。<apex:actionSupport>
    • 该属性指定 应触发更新的 DOM 事件。而仅执行 在“onClick”事件期间,可以执行 在任何有效事件(例如“onclick”)上, “ondblclick”,或者,在本例中, “onmouseover”。event<apex:commandLink><apex:actionSupport>
    • 属性 指定应刷新页面的哪一部分。reRender
    • 标签集 查询的值 string 参数。<apex:param>cid

该属性不是必需的。如果你不这样做 设置它,页面不会在指定事件时刷新,但仍设置 的名称和值。reRender≤apex:param>cid

生成的标记如下所示:

<apex:page standardController="Account">
    <apex:pageBlock title="Hello {!$User.FirstName}!">
        You are displaying contacts from the {!account.name} account. 
        Mouse over a contact's name to view his or her details.
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:form>
            <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" 
                               border="1">
                  <apex:column>
                      <apex:outputPanel>
                          <apex:actionSupport event="onmouseover" rerender="detail"> 
                              <apex:param name="cid" value="{!contact.id}"/>
                          </apex:actionSupport> 
                          {!contact.Name}
                      </apex:outputPanel> 
                  </apex:column>
            </apex:dataTable>
        </apex:form>
    </apex:pageBlock>
    <apex:outputPanel id="detail">
        <apex:actionStatus startText="Requesting...">
            <apex:facet name="stop">
                <apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" 
                                title="false"/>
            </apex:facet>
        </apex:actionStatus>
    </apex:outputPanel>
</apex:page>

保存页面后,将鼠标移到任何联系人上,并注意详细信息区域 在不单击它的情况下适当刷新。

将 Visualforce 页面放在外部域上

之后,您可以使用 iframe 将 Visualforce 内容放在受信任的外部域上 指定允许成帧的域。

在“设置”中,搜索 。在“点击劫持保护”下, 选择为禁用标题标准 标头。这两个选项都允许在受信任的外部域上建立框架,并且 提供点击劫持保护。Session Settings

然后,在“内联帧的受信任域”下,添加受信任的外部域,其中 允许框架并将 iframe 类型设置为 Visualforce Pages。确保 您的域名符合格式要求。您最多可以添加 512 个外部域。

将外部域添加到列表后,Visualforce 页面将使用 和 HTTP 标头进行呈现,以允许通过这些域进行框架设置。X-Frame-OptionsContent-Security-Policy

此代码演示如何在外部域上构建 Visualforce 页面。

<html>
    <head></head>
    <body>
        <iframe src="https://MyDomainName--PackageName.vf.force.com/apex/iframe"></iframe>
    </body>
</html>

注意

如果不是增强型域 在您的组织中启用,您的 URL 格式是不同的。有关详细信息,请参阅“我的域 URL 格式”中的“我的域 URL 格式”。 Salesforce 帮助。

Visualforce 开发工具

在开始开发 Visualforce 页面和组件之前,请熟悉不同的位置 要创建它们,请执行以下操作:

  • 构建 Visualforce 开发模式的最佳方式仅适用于具有“自定义”的用户 应用程序“权限。开发模式为您提供:
    • 每个 Visualforce 页面上包含页面视图的特殊开发页脚 状态、任何关联的控制器、指向组件参考文档的链接和页面 标记编辑器,提供突出显示、查找替换功能和自动建议 组件标记和属性名称。
    • 只需输入唯一的 URL 即可定义新的 Visualforce 页面。
    • 错误消息包含比标准用户更详细的堆栈跟踪 收到。
    要启用 Visualforce 开发模式,请执行以下操作:
    1. 从您的个人设置中,输入快速 “查找”框,然后选择“高级用户详细信息”。Advanced User Details没有结果?输入 “快速查找”框,然后选择“个人信息”。Personal Information
    2. 单击编辑
    3. 选中“开发模式”复选框。
    4. (可选)选中“在开发模式下显示视图状态”复选框以 启用开发页脚上的“视图状态”选项卡。此选项卡可用于监视 Visualforce 页面的性能。
    5. 点击保存
  • 您还可以通过 Salesforce 用户界面从设置中开发 Visualforce 页面 输入“快速查找”框,然后 选择 Visualforce 页面。对于 Visualforce 组件,请从“设置”中输入“快速查找”框,然后选择“Visualforce 组件”。Visualforce PagesComponents
  • 适用于 Visual Studio Code 的 Salesforce 扩展,其中包括 用于在轻量级、可扩展的 VS Code 编辑器中的 Salesforce 平台上进行开发的工具, 提供与开发组织(临时组织、沙箱和 DE 组织)合作的功能, Apex、Aura 组件和 Visualforce。

使用开发模式页脚

启用开发模式后,您可以通过导航到 页面的 URL。例如,如果某个页面被命名为 ,并且您的 Salesforce 实例是 MyDomainName.my.salesforce.com,请在浏览器的地址栏中输入 https:// MyDomainName.my.salesforce.com/apex/HelloWorld开发模式还为您提供了特殊的开发 页脚用于编辑 Visualforce 页面和自定义控制器,以及监控 Visualforce 性能。HelloWorld启用开发模式后,将显示所有 Visualforce 页面 使用浏览器底部的开发模式页脚:

  • 单击带有页面名称的选项卡以打开页面编辑器以查看和编辑 关联的 Visualforce 标记,而无需返回“设置”区域。变化 保存页面后立即显示。
  • 如果页面使用自定义控制器,则控制器类的名称可用作 一个选项卡。单击选项卡以编辑关联的 Apex 类。
  • 如果页面使用任何控制器扩展,则每个扩展的名称都可用 作为选项卡。单击该选项卡可以编辑关联的 Apex 类。
  • 如果在安装程序中启用,则“视图状态”选项卡将显示信息 关于影响 Visualforce 页面视图状态的项目。
  • 单击保存”(位于编辑窗格的正上方)以保存更改,然后 刷新页面内容。
  • 单击“组件引用”(Component Reference) 查看所有文档 支持的 Visualforce 组件。
  • 单击“在哪里使用?”以查看 引用页面的 Salesforce,例如自定义选项卡、控制器或其他 页面。
  • 单击“折叠”按钮 (“折叠”图标) 以折叠开发模式页脚 面板。单击“展开”按钮 (“展开”图标) 将其切换回打开状态。
  • 单击“禁用开发模式”按钮 (禁用开发模式图标) 以关闭 完全是开发模式。开发模式将保持关闭状态,直到您从 您的个人设置中的您的个人信息页面。

关于“视图状态”选项卡

网页的视图状态由以下所有数据组成 在服务器请求(如发送或接收数据)期间维护控制器的状态。 由于视图状态会影响页面的整体大小,因此页面的性能可以 依赖于有效管理视图状态。开发模式页脚中的“视图状态”选项卡 提供有关 Visualforce 页面与 Salesforce 交互时的视图状态的信息。

注意

了解页面请求过程的开发人员应使用“视图状态”选项卡。 在使用 标签。要启用“视图状态”选项卡,请执行以下操作:

  1. 从您的个人设置中,输入 “快速查找”框,然后选择“高级用户详细信息”。Advanced User Details没有结果?进入 “快速查找”框,然后选择“个人信息”。Personal Information
  2. 单击编辑
  3. 选中“开发模式”复选框(如果未选中)。
  4. 选中“在开发模式下显示视图状态”复选框。
  5. 点击保存

注意

由于视图状态链接到表单数据,因此“视图状态”选项卡仅在 页面包含标签。此外, “视图状态”选项卡仅在使用自定义控制器或控制器扩展的页面上显示。<apex:form>

“视图状态”选项卡由文件夹节点组成。如果单击任何文件夹,则饼图中带有 此时将显示“内容”选项卡。此图表显示文件夹的子 Visualforce 自定义控制器 Apex 对象或字段。您可以通过以下方式查看哪些元素对父项的整体大小有影响 将鼠标悬停在图形的各个部分上。这与各个文本节点的信息相同。 该图表要求在浏览器上启用 Flash 版本 6 或更高版本。Salesforce 允许 Visualforce 页面的最大视图状态大小为

170KB.“视图状态”选项卡显示页面上的哪些元素是 占用了这个空间。较小的视图状态大小通常意味着更快的加载时间。最小化 页面的视图状态,您可以优化 Apex 控制器代码并删除任何多余的 使用的 Visualforce 组件。例如:

  • 如果您注意到很大一部分视图状态 来自控制器或控制器扩展中使用的对象,请考虑优化 SOQL 调用以仅返回与 Visualforce 页面相关的数据。
  • 如果视图状态受大型组件的影响 树,尝试减少页面所依赖的组件数量。

“视图状态”选项卡包含以下列(按字母顺序):

描述
占家长的百分比自定义控制器、Apex 对象或字段占总大小的百分比 为父母做出贡献。
名字自定义控制器、Apex 对象或字段的名称。
大小自定义控制器、Apex 对象或字段的视图状态大小。
类型自定义控制器、Apex 对象或字段的类型。
价值字段的值。

“名称”列包含定义 Visualforce 页面各个部分的节点。它们是(按字母顺序排列):

节点描述
组件树这代表了页面的整体结构。其大小受 页面上的组件数。一般来说,更少的组件意味着更小 组件树,这可能会导致更快的加载时间。您可以查看您的视图量 状态大小由组件树组成,方法是单击“视图” 状态文件夹。
内部这表示您的 Visualforce 页面使用的内部 Salesforce 数据。这不可能 由开发人员控制。您可以看到视图状态大小的构成 内部元素,方法是单击“状态”文件夹。
表达 式这表示 Visualforce 页面中定义的公式表达式使用的数据。
此文件夹包含所有 Visualforce 自定义控制器 Apex 对象或字段。通过展开子 Controller 和 Controller Extension 文件夹,您可以 可以查看页面上的每个对象、其字段以及这些字段的值。 通常,这些取决于您的 Apex 控制器逻辑。
视图状态此文件夹包含所有节点。通过单击它,您可以找到整体 有关 Visualforce 的信息 页面的视图状态。“容量”选项卡告诉您分配的视图状态大小是多少 正在使用。如果超过该数量,该图表还会告诉您有多少 KB 你已经过去了。

关于 Visualforce 编辑器

通过开发模式页脚或从“设置”编辑 Visualforce 页面时,编辑器 具有以下功能:语法高亮显示编辑器会自动对关键字和所有关键字应用语法高亮显示 函数和运算符。搜索 (搜索图标)通过搜索,可以在当前页面、类或 触发。若要使用搜索,请在“搜索”文本框中输入字符串,然后单击“查找下一个”。

  • 要将找到的搜索字符串替换为另一个字符串,请输入新的 字符串,然后单击“替换”以仅替换该实例,或单击“全部替换”以替换该实例,然后单击“全部替换”以替换该实例,然后单击“替换” 页面中出现的搜索字符串的所有其他实例, 类或触发器。
  • 若要使搜索操作区分大小写,请选择“匹配大小写”选项。
  • 若要使用正则表达式作为搜索字符串,请选择“正则表达式”选项。常规 表达式遵循 JavaScript 的正则表达式规则。搜索 使用正则表达式可以找到换行超过 一行。如果将 replace 操作与 找到的字符串一起使用 一个正则表达式,替换操作也可以绑定 正则表达式组变量(、 等) 找到搜索字符串。例如,要将标签替换为标签,并保留所有 属性对原来完好无损,搜索并替换它 跟。$1$2<h1><h2><h1><h1(\s+)(.*)><h2$1$2>

转到行 (“转到行”图标)
此按钮允许您突出显示指定的行号。如果该行是 当前不可见,编辑器将滚动到该行。
撤消 (“撤消”图标) 和重做 (“重做”图标)
使用撤消可撤消编辑操作,使用重做可重新创建编辑操作 那被撤消了。
字体大小
从下拉列表中选择字体大小以控制 编辑器中显示的字符。
行和列位置
光标的行和列位置显示在状态栏中 编辑器的底部。这可以与转到行 (“转到行”图标) 一起使用,以快速浏览编辑器。
行数和字符数
行数和字符总数显示在状态栏中 编辑器的底部。
编辑器支持以下键盘快捷键:
Tab
在光标处添加一个选项卡
SHIFT+Tab
删除选项卡
CTRL+f
打开搜索对话框或搜索当前 搜索
CTRL+r
打开搜索对话框或替换当前 使用指定的替换字符串进行搜索
CTRL+g
打开“转到行”对话框
CTRL+s
执行快速保存。
CTRL+z
撤消上次编辑操作
CTRL+y
重新创建上次撤消的编辑操作

访问 Visualforce 页面的指标

要查询组织中 Visualforce 页面上的指标,请使用 Salesforce SOAP 中的对象 应用程序接口。

VisualforceAccessMetrics

要从对象中查询信息,请使用开发人员控制台中的查询编辑器。如果使用 Visual Studio Code,则可以 还可以使用 SOQL Builder 进行查询,SOQL Builder 是 Salesforce Extension Pack 的一部分。VisualforceAccessMetrics

下面是一个 SOQL 调用示例:

SELECT ApexPageId, DailyPageViewCount, Id, ProfileId, MetricsDate, LogDate FROM VisualforceAccessMetrics
参数描述
日志日期此参数提供记录页面访问的日期。此参数 适用于版本 216 及更高版本。
配置文件 Id与访问页面的用户关联的配置文件的 ID。这 参数可用于版本 216 及更高版本。
ApexPageId跟踪的 Visualforce 页面的 ID
每日页面浏览每个对象跟踪 字段中的每日页面查看次数。VisualforceAccessMetricsDailyPageViewCount
指标日期中指定了收集衡量指标的日期。MetricsDate

注意

页面查看量在页面查看后的第二天进行统计,每个对象在 90 次后删除 日。VisualforceAccessMetrics

使用 , 你 可以跟踪组织中每个 Visualforce 页面在 24 小时内收到的浏览次数 时期。要了解页面在多天内获得了多少浏览量,您可以查询 同一 ApexPageId 的多个对象。VisualforceAccessMetricsVisualforceAccessMetrics

Visualforce 简介

Visualforce 由一种基于标签的标记语言组成,可为开发人员提供 构建应用程序和自定义 Salesforce 用户界面的方式。借助 Visualforce,您可以:

  • 生成向导和其他多步骤过程。
  • 通过应用程序创建自定义流控制。
  • 定义导航模式和特定于数据的规则,以实现最佳、高效的应用程序 互动。

有兴趣创建新的 Visualforce 组件吗?我们建议构建闪电网络 组件。它们是适用于 Salesforce 的更现代、更强大的自定义 HTML 元素 应用和网站。如果您仍然对为什么要使用 Lightning Web 组件感到好奇 而不是 Visualforce,而是 find 现在更多了。

Visualforce 可用于桌面浏览器和 Salesforce 移动应用程序。对于桌面 浏览器,它在 Lightning Experience 和 Salesforce Classic 中都可用。Lightning 不支持 Visualforce 页面和自定义 iframe 在 iPad Safari 上体验。Visualforce 在 Contact Manager、Group、 专业版、企业版、无限制版、性能版和开发人员版。

什么是 Visualforce?

Visualforce 是一个框架,允许开发人员 构建可在 Lightning 平台上本地托管的自定义用户界面。这 Visualforce 框架包括一种类似于 HTML 的基于标记的标记语言。它还有一个 一组服务器端“标准控制器”,用于执行基本数据库操作, 如查询和保存,执行简单。

我们建议使用 Lightning Web 组件而不是 Visualforce 来构建自定义功能。 Lightning Web 组件是轻量级的,可为您的应用程序提供卓越的性能,并且 网站。详细了解为什么要使用 Lightning Web 组件而不是 Visualforce。

在 Visualforce 标记语言中,每个 Visualforce 标签对应于一个粗略的或 细粒度用户界面组件,例如页面分区、相关列表或字段。这 Visualforce 组件的行为可以通过 标准 Salesforce 页面。或者,开发人员可以将自己的逻辑与 用 Apex 编写的 controller 类。

Visualforce 组件及其示例 对应标签

什么是 Visualforce 页面?

开发人员可以使用 Visualforce 创建 Visualforce 页面定义。页面定义 由两个主要元素组成:

  • Visualforce 标记
  • Visualforce 控制器

Visualforce 标记

Visualforce 标记由 Visualforce 标签、HTML、JavaScript 或任何其他支持 Web 的标记组成 代码嵌入在单个标签中。 标记定义页面上包含的用户界面组件以及方式 他们出现了。<apex:page>

Visualforce 控制器

Visualforce 控制器是一组指令,用于说明所发生的情况 当用户与关联的 Visualforce 标记中指定的组件进行交互时。一种类型 交互是指用户单击按钮或链接时。控制器还提供对 页面中显示的数据,可以修改组件行为。开发人员可以使用 Lightning 平台提供的标准控制器,也可以添加 自定义控制器逻辑,其类是用 Apex 编写的:

  • 一个标准 控制器由用于 标准 Salesforce 页面。例如,如果您使用 标准帐户控制器,单击 Visualforce 页面的行为与在标准帐户编辑页面上单击“保存”的行为相同。如果您在页面上使用标准控制器,并且用户无权访问 对象,则页面显示权限不足错误消息。解决此错误 通过检查用户对对象的可访问性,以及 适当地显示组件。
  • 通过标准列表控制器,您可以创建 Visualforce 页面,这些页面可以 显示或处理一组记录。现有 Salesforce 页面的示例 一组记录包括列表页、相关列表和批量操作页。
  • 自定义控制器是用 Apex 编写的类,它 实现页面的所有逻辑,而无需利用标准控制器。如果您使用 自定义控制器,您可以定义新的导航元素或行为,但必须 此外,还要重新实现标准控制器中已提供的任何功能。与其他 Apex 类一样,自定义控制器完全在系统模式下执行,在 忽略当前用户的对象级和字段级权限。您可以 指定用户是否可以根据用户的 轮廓。
  • 控制器扩展是用 Apex 编写的类,它 添加或覆盖标准或自定义控制器中的行为。扩展允许您 以使用另一个控制器的功能,同时添加您自己的自定义逻辑。标准控制器在用户模式下执行,其中权限为字段级 强制执行当前用户的安全性和共享规则。扩展标准 控制器允许您构建尊重用户权限的 Visualforce 页面。 尽管扩展类在系统模式下执行,但标准控制器执行 在用户模式下。与自定义控制器一样,您可以指定用户是否可以执行 基于用户配置文件的控制器扩展中的方法。

注意

自定义控制器和控制器扩展类在 系统模式,因此它们会忽略用户权限和字段级安全性。但是,您可以 选择是否遵循用户在组织范围内的默认值、角色层次结构和共享 规则,方法是使用 类定义。有关信息,请参阅《使用 、 和关键字》中的“使用 Apex 开发人员 指南。with sharingwith sharingwithout sharinginherited sharing

Visualforce 页面可以在哪里使用?

开发人员可以使用 Visualforce 页面执行以下操作:

  • 替代标准按钮,例如帐户的“新建”按钮, 或联系人的“编辑”按钮
  • 覆盖选项卡概述页面,例如“帐户”选项卡主页
  • 定义自定义选项卡
  • 在详细信息页面布局中嵌入组件
  • 创建仪表板组件或自定义帮助页面
  • 自定义、扩展或集成 Salesforce 控制台中的侧边栏(自定义控制台 组件)
  • 在 Salesforce 移动应用程序中添加导航菜单项和操作

为什么我应该使用 Lightning Web 组件而不是 视觉力?

对于新的开发,Salesforce 建议使用 Lightning Experience 低代码工具和 Visualforce 上的闪电网络组件,可实现最现代、高性能和响应速度最快的功能 功能性。Lightning Platform 为高级管理员和 开发人员构建自定义功能,它支持更新、复杂的业务流程 不适用于 Visualforce。

如果您有现有的 Visualforce 组件,请将其转换为 Lightning Web 组件 提供优化和改进应用的机会。花时间评估整体设计 以及每个组件及其等效组件的可用性。与您的设计师合作,选择最好的 使您的组件与 Lightning Experience 用户的现代外观保持一致的方法 接口。有关灵感和一些示例代码,请参阅 Lightning 中提供的组件蓝图 设计系统。

在开始开发 Lightning Web 组件时,请确定何时重用 Visualforce 页面 以及何时将其重建为 Lightning Web 组件。考虑 在需要时进行重建:

  • 更具吸引力和响应性的用户体验。
  • 支持最新的 Web 内容可访问性指南 (WCAG)。
  • 一种易于针对多种设备外形规格进行优化的体验。
  • 提高应用性能。

Lightning Web 组件

Lightning Web 组件是使用 HTML 和现代 JavaScript 构建的自定义 HTML 元素。他们 使用核心 Web 组件标准,仅提供在浏览器中良好运行所需的内容 由 Salesforce 提供支持。因为它们是建立在浏览器中本地运行的代码之上的,所以 Lightning Web 组件是轻量级的,并提供卓越的性能。

Visualforce 标准组件和基本 Lightning Web 组件端

使用此表可查找特定 Lightning Web 组件的等效基本 Lightning Web 组件 标准 Visualforce 组件。

Visualforce 组件Lightning Web 组件
apex:pageBlocklightning-card
apex:pageBlockButtons设置操作槽lightning-card
apex:pageBlockSectionlightning-accordionlightning-accordion-section
apex:pageBlockSectionItemlightning-layoutlightning-layout-item
apex:toolbarGrouplightning-layoutlightning-layout-item
apex:panelGridlightning-layoutlightning-layout-item
apex:panelGrouplightning-layoutlightning-layout-item
apex:tabPanellightning-tabset
apex:tablightning-tab
apex:repeattemplate for:each or iterator
apex:pageBlockTablelightning-datatable
apex:dataTablelightning-datatable
apex:inlineEditSupportlightning-datatable使用内联编辑 可编辑的列
apex:imagelightning-platform-resource-loader
apex:stylesheetlightning-platform-resource-loader
apex:includeScriptlightning-platform-resource-loader
apex:maplightning-map
apex:formlightning-record-form lightning-record-view-form lightning-record-edit-form
apex:inputlightning-inputlightning-slider
apex:inputCheckboxlightning-inputtype=“复选框”lightning-input类型=“复选框按钮”
apex:inputFilelightning-input类型=“文件”lightning-file-upload
apex:inputHiddenlightning-inputclass=“slds-hide”
apex:inputSecretlightning-inputtype=“密码”
apex:inputTextlightning-inputtype=“文本”
apex:inputTextArealightning-textarea
apex:inputFieldlightning-input-field
apex:selectCheckboxeslightning-checkbox-group
apex:selectListlightning-comboboxlightning-dual-listbox
apex:selectRadiolightning-radio-group
apex:outputLabel将标签属性设置为lightning-input
apex:outputFieldlightning-output-field
apex:outputLinklightning-formatted-url
apex:outputTextlightning-formatted-datetime lightning-formatted-number lightning-formatted-rich-text lightning-formatted-text lightning-formatted-time
apex:commandButtonlightning-button lightning-button-stateful lightning-button-icon lightning-button-icon-stateful
apex:commandLinklightning-button带裸露的变体
apex:pageMessagelightning-platform-show-toast-event
apex:messagesapex:message自定义有效性lightning-input
apex:pageMessages自动lightning-record-form用于或lightning-messageslightning-record-view-form lightning-record-edit-form

Visualforce 开发需要哪些权限?

Visualforce 开发需要 各种权限,具体取决于特定活动。

所需的用户权限
启用 Visualforce 开发模式:“自定义应用程序”
要创建、编辑或删除 Visualforce 页面:“自定义应用程序”
要创建和编辑自定义 Visualforce 组件,请执行以下操作:“自定义应用程序”
编辑自定义 Visualforce 控制器或 Apex“作者顶点”
设置 Visualforce 页面 安全:“管理配置文件和权限集”
要为 Visualforce 页面设置版本设置:“自定义应用程序”
要创建、编辑或删除静态资源,请执行以下操作:“自定义应用程序”
创建 Visualforce 制表符:“自定义应用程序”

Visualforce 是如何构建的?

所有 Visualforce 页面都完全在 Lightning 平台上运行,当开发人员创建 页面,以及最终用户请求页面时,如以下体系结构图所示。

Visualforce 系统架构 – 开发 模式

当开发人员完成 Visualforce 页面的编写并将其保存到平台时,平台应用程序服务器 尝试将标记编译为一组抽象指令 Visualforce 渲染器可以理解。如果编译产生错误,则保存将中止,并且 错误将返回给开发人员。否则,说明 保存到元数据存储库并发送到 Visualforce 渲染器。渲染器将指令转换为 HTML,然后 刷新开发人员的视图,从而提供即时反馈 向开发人员提供对标记所做的任何更改。

下面的架构图显示了非开发人员 用户请求 Visualforce 页面。因为页面已经编译成指令,所以 Application Server 只是从元数据存储库中检索页面 并将其发送到 Visualforce 渲染器以转换为 HTML。

Visualforce 系统架构 – 标准用户模式

注意

您的 Visualforce 页面可能在其中一台 force.com 服务器上运行,而不是在 salesforce.com 上运行 服务器。

Visualforce 页面与 S-Controls 相比如何?

重要

Visualforce 页面取代了 S 控件。尚未这样做的组织 以前使用的 S 控件无法创建它们。现有的 s 控制是 不受影响,仍可编辑。Visualforce 页面被认为是下一代 s-controls 和 应尽可能使用代替 S 控制,以提高性能和 编写它们的难易程度。下表概述了 Visualforce 页面和 S 控件。

Visualforce 页面S-控制
所需的技术技能HTML、XMLHTML、JavaScript、Ajax 工具包
语言风格标记标记程序代码
页面覆盖模型使用标签组装标准和自定义组件为整个页面编写 HTML 和 JavaScript
标准 Salesforce 组件库是的
访问内置平台行为是,通过标准控制器
数据绑定是的开发人员可以将输入组件(例如文本框)与特定的 字段(例如帐户名称)。如果用户在该输入组件中保存了一个值,则该值也是 保存在数据库中。不开发人员无法将输入组件与特定字段绑定。相反,他们 必须编写使用 API 的 JavaScript 代码,以使用用户指定的数据库更新 字段值。
样式表继承是的不可以,必须手动引入 Salesforce 样式表
尊重字段元数据,例如唯一性是,默认情况下如果用户尝试保存违反唯一性的记录,或者 必填字段属性,则会自动显示错误消息,用户可以 再试一次。是,如果使用 API 调用在 JavaScript 中编码describe如果用户尝试保存违反唯一性或要求的记录 字段属性,则仅当 S-Control 开发人员编写代码时才会显示错误消息 检查了这些属性。
与 Apex 的交互直接,通过绑定到自定义控制器间接,通过使用 Apex 方法 通过 APIwebService
性能响应速度更快,因为标记是在 Lightning 平台上生成的响应速度较慢,因为每次调用 API 都需要往返于 服务器 — 调整性能的重担由开发人员承担
页面容器本地在 iFrame 中

如何对 Visualforce 进行版本控制?

从 09 年夏季版本开始,Visualforce 页面和组件 已进行版本控制。当页面或组件具有版本号时,其功能 较旧的 Visualforce 元素不会随着新实现的引入而更改。Visualforce 版本从 15.0 开始。如果您尝试将 Visualforce 页面的版本设置为 15.0 之前的版本,会自动更改为 15.0。

为了帮助向后兼容,每个 Visualforce 页面和自定义 组件与指定版本的 API 的版本设置一起保存,以及 Visualforce 的特定版本。如果 Visualforce 页面或组件引用 已安装的托管包,每个托管包的版本设置 页面或组件也会被保存。这确保了作为 Visualforce、API 和 托管软件包中的组件在后续版本、Visualforce 页面和 组件仍绑定到具有特定已知行为的版本。

自定义组件 在 Visualforce 页面中引用,始终在自己的版本号下执行。因此,如果 自定义组件设置为版本 15.0,它始终表现出 Visualforce 版本的行为 15.0,无论是在版本 15.0 还是 16.0 页面中运行。

发行说明列出了 Visualforce 版本。组件参考还列出了标准组件的 Visualforce 版本 引入,以及组件或属性是否在版本中被弃用。设置 Visualforce 的 Salesforce API 和 Visualforce 版本 页面或自定义组件:

  1. 编辑 Visualforce 页面或组件,然后单击版本设置。注意您只能修改 “版本设置”中页面或自定义组件的版本设置 选项卡,在“设置”中编辑页面或组件时。
  2. 选择 Salesforce API 的版本。这也是 与页面或组件一起使用的 Visualforce 版本。
  3. 点击保存

测试 Lightning Web 组件

Jest 是一个强大的工具,具有丰富的功能,可用于编写 JavaScript 测试。使用 Jest 为所有 Lightning Web 组件编写单元测试。

在命令行中运行 Jest 测试,或者在 IDE 中(通过一些配置)运行 Jest 测试。Jest 测试不会在浏览器中运行,也不会连接到组织,因此它们运行速度很快。在“监视模式”下运行时,它们会在您编码时为您提供即时反馈。Jest 测试仅适用于 Lightning Web 组件,不适用于 Aura 组件。

将 Jest 测试编写到:

  • 单独测试组件
  • 测试组件的公共 API(属性和方法、事件)@api
  • 测试基本用户交互(点击次数)
  • 验证组件的 DOM 输出
  • 验证事件是否按预期触发

提示

lwc-recipes 存储库中充满了 Jest 测试。在 的 Lightning Web 组件的文件夹中查找 Jest 测试。__tests__force-app/main/default/lwc

安装sfdx-lwc-jest

安装及其依赖项到每个 Salesforce DX 项目中。 仅适用于 Salesforce DX 项目。sfdx-lwc-jestsfdx-lwc-jest

先决条件

在安装之前,请安装 Node.js 和 npm。sfdx-lwc-jest

  • 节点.js此页面列出了 Node.js 的两个版本。我们建议使用“LTS”(长期支持)版本,而不是“当前”版本。
  • npm安装 Node.js 时,npm 也会安装。不过,您可能需要更新 npm,因此请访问 npm 网站以获取说明。

使用 Salesforce CLI 将 Jest 及其依赖项安装到您的项目中

安装 Jest 及其依赖项的最简单方法是运行 Salesforce CLI 命令 sf force lightning lwc test setup。从每个 Salesforce DX 项目的顶级目录运行命令。此命令将创建必要的配置文件并为您安装软件包。sfdx-lwc-jest

手动安装 Jest 及其依赖项

如果您在无法使用 Salesforce CLI 的环境中工作,您可以自行设置测试依赖项。

要安装及其依赖项,请从每个 Salesforce DX 项目的顶级目录运行这些命令一次。sfdx-lwc-jest

npm install
npm install @salesforce/sfdx-lwc-jest --save-dev

默认情况下,SFDX 项目在其文件块中包含这些脚本条目。如果项目文件不包含它们,请添加它们。scriptspackage.json

{
  ...
  "scripts": {
    ...
    "test": "npm run test:unit",
    "test:unit": "sfdx-lwc-jest",
    "test:unit:watch": "sfdx-lwc-jest --watch",
    "test:unit:debug": "sfdx-lwc-jest --debug",
    "test:unit:coverage": "sfdx-lwc-jest --coverage",
    ...
  },
  ...
}

运行 Lightning Web 组件的 Jest 测试

在组件开发过程中频繁或持续运行单元测试。

从 VS Code 运行测试

如果安装适用于 Visual Studio Code 的 Salesforce 扩展,则可以在 VS Code 中运行测试、调试测试和监视 Jest 文件。有关详细信息,请参阅适用于 Visual Studio Code 的 Salesforce 扩展。

在命令行上运行测试

要运行项目的所有测试,请使用 Salesforce CLI 命令 sf force lightning lwc test run from your root folder of your project。否则,请运行在安装 Jest 和 dependencies 时添加到项目文件块的命令。scriptspackage.json

npm run test:unit

在开发过程中持续运行测试

若要在每次保存更改时对单个组件运行所有测试,请转到组件目录并运行带有参数的命令。使用您在安装 Jest 和依赖项时添加到项目文件块的条目。sfdx-lwc-jest--watchscriptspackage.json

npm run test:unit:watch

Jest 会监视所有组件文件的更新,并在每次检测到更改时运行所有相关测试。

在调试模式下运行 Jests 测试

如果要逐步执行测试和应用代码,以找出测试或代码未按预期运行的原因,则在调试模式下运行 Jest 测试非常有用。您可以使用以下工具调试 Jest 测试。

  • VS Code Salesforce 扩展包
  • Chrome 开发者工具
  • VS Code 调试器高级配置

VS Code Salesforce 扩展包提供了最简单、最直接的选项,而 Chrome DevTools 则迎合了经验丰富的 Web 开发人员的需求。此外,VS Code 调试器的高级配置使你能够使用不同的调试器和调试方案。高级配置为调试 Jest 测试提供了最灵活的选项。

有关更多信息,请参阅调试 Lightning Web 组件的 Jest 测试。

高级 Jest 配置

sfdx-lwc-jest配置为运行 Jest 测试,无需任何其他更改。但是,如果您是 Jest 的高级用户,请查看 Jest 的其他一些配置选项。请参见 github.com/salesforce/sfdx-lwc-jest#overriding-jest-config

重要

如果你的 Jest 测试执行缓慢,并且它们有来自不同文件夹的依赖项,请提供映射以加快解析速度。请参阅 lwc-recipes 存储库中的 。moduleNameMapper

调试 Lightning Web 组件的 Jest 测试

VS Code 提供了一些工具来帮助你有效地调试 Jest 测试。根据您的测试要求,使用 Salesforce 扩展包、Chrome DevTools 或 VS Code 调试器高级配置。

使用 Salesforce 扩展包调试测试

适用于 Visual Studio Code 的 Salesforce 扩展提供了一个 LWC 测试侧边栏,供您轻松运行测试。可以运行一个测试用例、一个文件中的所有测试用例或项目的所有测试。有关详细信息,请参阅 LWC 测试侧栏中的功能概述。

若要调试测试,请在测试中添加断点。

例如,如果要确保正确调度事件,请单击包含方法的行号 (1)。您还可以在组件的 JavaScript 文件中的事件处理程序上添加断点,以观察事件处理程序的触发时间。dispatchEvent()

添加断点后,单击“调试测试”(2)。此链接运行以下命令:。node --inspect-brk node_modules/.bin/jest --runInBand

提示

请参阅 lwc-recipes 存储库。helloConditionalRendering.test.js

在“运行”视图中显示与运行和调试相关的信息。

若要打开“运行”视图,请单击“运行和调试”(1),您可以在其中查看表达式 (2),并使用调试工具栏 (3) 单步执行测试。在调试控制台 (4) 中,可以在测试执行时检查元素。

单击调试工具栏 (3) 上的“继续”以单步执行断点。如果未收到错误,则测试将成功完成。在 VS Code 终端中查看任何测试执行输出。

调试 Jest Salesforce 扩展

https://youtube.com/watch?v=OOGn0JLabS0

提示

有关更多调试技术,请参阅从文件内运行、调试或观看 Jest 测试。

使用 Chrome DevTools 调试测试

虽然 Salesforce 扩展包使您能够从 VS Code 中调试 Jest 测试,但 Chrome DevTools 为您提供了用于 Web 开发的全面诊断功能。

若要在调试模式下运行项目中的所有测试,请在 VS Code 终端中输入此命令。

npm run test:unit:debug

此命令调用 ,然后运行 。sfdx-lwc-jest --debugnode --inspect-brk node_modules/.bin/jest --runInBand

注意

我们建议您使用该命令,因为该命令已解析为节点依赖项,并且无法在命令行上访问。npm run test:unit:debugsfdx-lwc-jest

若要在调试模式下运行单个测试,请输入此命令,其中要调试的测试的名称。testName

npm run test:unit:debug -- testName

接下来,打开 Chrome 浏览器并转到 。“远程目标”部分列出了在调试模式下在系统中运行的所有节点进程。chrome://inspect

若要打开“DevTools”窗口,请单击“远程目标”部分中列出的“Jest 测试”下的“检查”链接。

使用“DevTools 源”面板可以调试测试。首先,在 VS Code 的测试代码中添加一条语句。debugger

注意

Chrome 检查器不会单步执行你在上一部分的 VS Code 中指定的断点。请改用测试中的语句。debugger

若要恢复测试执行,请单击 DevTools 中的“恢复脚本执行 (Resume icon)”按钮。测试将显示您的测试代码,并在您添加的语句处停止,如已编译代码的第 36 行所示。然后,可以在“源”面板中添加断点,如此屏幕截图中的第 37 行所示。debugger

提示

有关使用 Chrome DevTools 的更多调试技术,请参阅调试 JavaScript。

如果需要更好地控制如何在调试模式下运行 Jest 测试,请考虑使用 VS Code 高级配置。

使用 Chrome 开发者工具调试 Jest 测试

https://youtube.com/watch?v=TDHCrLAn33E

使用 VS Code 高级配置调试 Jest 测试

VS Code 允许你配置在调试模式下运行 Jest 测试的方式。

要使用高级配置,请执行以下操作:

  1. 生成启动配置文件。
    1. 在“运行”视图中,单击“创建 launch.json 文件”链接。从“运行和调试”选项卡生成 launch.json 文件
    2. 在显示的下拉列表中,选择“Node.js”,这将为您创建一个文件。将 的内容替换为 sfdx-lwc-jest 存储库的 Visual Studio Code 中的调试中所示的配置。launch.jsonlaunch.json注意Mac 和 Windows 用户的配置不同。按照 sfdx-lwc-jest 存储库中的说明查找操作系统的配置。若要为不同的调试器和调试方案自定义启动配置,请使用 VS Code 的 launch.json 属性。
  2. 在 Salesforce DX 项目的根目录下添加一个 Jest 配置文件。在此文件中,包括 sfdx-lwc-jest 存储库中覆盖 Jest Config 中提供的配置代码。配置代码如下所示。jest.config.jsconst { jestConfig } = require("@salesforce/sfdx-lwc-jest/config"); module.exports = { ...jestConfig, // add any custom configurations here };
  3. 在测试代码和组件的 JavaScript 文件中添加语句。debugger注意使用 VS Code 中的高级配置进行调试时,不支持添加断点。添加断点的行号与编译文件中的行号不匹配。请改用该语句。debugger
  4. 启动配置文件。转到“运行”视图。选择 Debug Jest Tests 配置,然后单击 Start Debugging (“开始调试”图标)。默认情况下,此命令运行项目中的所有测试,并在测试代码和组件的 JavaScript 文件中添加的所有调试器语句中停止。可以在 VS Code 终端中查看执行输出,并使用 VS Code 中的调试功能,例如使用调试控制台检查变量。

使用 VSCode 调试器高级配置调试 Jest 测试

https://youtube.com/watch?v=x3EbNOiczm4

提示

有关解决 Jest 问题的信息,请参阅 jestjs.io/docs/en/troubleshooting

为 Lightning Web 组件编写 Jest 测试

在本地 JavaScript 文件中编写组件测试。将它们与组件本身一起提交到版本控制中。Jest 测试不会保存到 Salesforce。

Jest 测试的编写、保存和运行方式与为 Lightning 测试服务编写的 Jasmine 或 Mocha 测试不同。Jest 测试仅是本地测试,并且独立于 Salesforce 保存和运行。

您可以使用 Salesforce CLI 命令 sf force lightning lwc test create 在目录中创建测试目录和样板测试文件。以下命令创建用于测试 Lightning Web 组件的测试目录和文件。myButton

sf force lightning lwc test create -f force-app/main/default/lwc/myButton/myButton.js

组件文件夹结构

使用 Salesforce CLI 命令后,您会看到在组件的捆绑包目录的顶层命名的文件夹,例如 .否则,请自行创建文件夹。将此组件的所有测试保存在文件夹中。通过将文件夹提交到版本控制,与其他团队成员或系统共享测试。create__tests__force-app/main/default/lwc/myButton/__tests____tests____tests__

更新 .forceignore

要确保文件夹及其内容永远不会保存到 Salesforce,请将此 glob 模式添加到每个项目的文件中。Salesforce CLI 命令 sf force lightning lwc test setup 会为您执行此任务。__tests__.forceignore

**/__tests__/**

此模式可确保推送、拉取或转换代码和元数据的 Salesforce DX 命令忽略文件夹及其内容。__tests__

测试文件命名约定

Jest 在目录中运行 JavaScript 文件。测试文件的名称必须以 结尾,我们建议测试以 结尾。可以使用一个包含所有组件测试的测试文件,也可以使用多个文件来组织相关测试。测试文件可以放在子文件夹中。__tests__.js.test.js

编写基本测试

要成为一名有成就的测试人员,请学习如何使用 Jest。特别是,学习 Jest 提供的许多匹配器的语法。我们在这里不介绍 Jest 的一般用法,因为 Jest 文档非常出色。我们专注于将 Jest 与 Lightning Web 组件一起使用的细节。

Lightning Web 组件的 Jest 测试应该单独测试单个组件的行为,对外部组件或服务的依赖性最小。

让我们看一下,这是对 lwc-recipes 存储库中 Lightning Web 组件的测试。hello.test.jshello

// hello.test.js
import { createElement } from "lwc";
import Hello from "c/hello";

describe("c-hello", () => {
  afterEach(() => {
    // The jsdom instance is shared across test cases in a single file so reset the DOM
    while (document.body.firstChild) {
      document.body.removeChild(document.body.firstChild);
    }
  });

  it("displays greeting", () => {
    // Create element
    const element = createElement("c-hello", {
      is: Hello,
    });
    document.body.appendChild(element);

    // Verify displayed greeting
    const div = element.shadowRoot.querySelector("div");
    expect(div.textContent).toBe("Hello, World!");
  });
});

让我们演练一下代码,并了解测试文件的每个部分。所有测试都必须使用此结构。

进口

首先,测试导入方法。此方法仅在测试中可用。代码还必须导入要测试的组件,在本例中为 .稍后使用这些导入来创建受测组件。createElementc/hello

import { createElement } from "lwc";
import Hello from "c/hello";

描述块

模块定义测试套件。测试套件包含一个或多个测试,从功能角度来看,这些测试属于一起。describe

describe('c-hello', () => {
  ...
});

我们建议使用一个顶级块,其描述与组件名称匹配。仅在必要时添加更多对功能进行分组的块。describedescribe

对于 ,单个就足够了。对于更复杂的组件,使用多个块将事物分组为错误场景、空输入、有线数据、常规数据等类别可能是有意义的。hello.test.jsdescribedescribe

在测试之间清理

Jest afterEach() 方法在测试结束时重置 DOM。

由于测试运行时浏览器没有运行,因此 Jest 用来提供一个行为与浏览器的 DOM 或 .Jest 依赖于 ,这是一个 Node.js 项目,因此在项目安装过程中下载的方式与 Jest 本身相同。jsdomdocumentjsdomjsdomsfdx-lwc-jest

每个测试文件共享一个 的实例,并且文件内的测试之间不会重置更改。因此,最佳做法是在测试之间进行清理,以便测试的输出不会影响任何其他测试。jsdom

afterEach(() => {
  // The jsdom instance is shared across test cases in a single file so reset the DOM
  while (document.body.firstChild) {
    document.body.removeChild(document.body.firstChild);
  }
});

Jest 还具有其他可用于执行设置和清理任务的方法。请参见 jestjs.io/docs/en/setup-teardown

IT(或测试)块

注意

it是 test 的别名。使用任何可以让您准确描述预期行为的词。

块描述单个测试。测试表示要测试的单个功能单元。编写 以描述该函数的预期行为。例如,该组件显示“Hello, World!”,因此该块会测试 hello 组件是否显示问候语。itithelloit

it('displays greeting', () => {
    ...
});

创建测试组件

该测试使用导入的方法创建要测试的组件的实例,在本例中为 .createElementc-hello

const element = createElement("c-hello", {
  is: Hello,
});

将测试组件添加到 DOM 中

然后,测试调用以将组件添加到测试的 版本 中。appendChilddocument

调用将组件插入到 DOM 和生命周期钩子中,然后被调用。appendChild()connectedCallback()renderedCallback()

document.body.appendChild(element);

下一步是使用标准的 DOM 查询方法在 DOM 中搜索元素。用作查询的父级。这是一个仅限测试的 API,可让您查看阴影边界以检查组件的阴影树。它等效于 .element.shadowRootthis.template

const div = element.shadowRoot.querySelector("div");

使用断言

最后,该语句是对成功条件的断言:元素的文本为“Hello, World!”expect

const div = element.shadowRoot.querySelector("div");
expect(div.textContent).toBe("Hello, World!");

Jest 支持许多匹配器,例如 和,这使得检查值是否满足条件变得容易。请参见 jestjs.io/docs/en/expecttoBetoMatchObject

测试异步 DOM 更新

当 Lightning Web 组件的状态发生变化时,DOM 会异步更新。若要确保测试在评估结果之前等待更新完成,请返回已解析的 Promise。将测试代码的其余部分链接到解析的 Promise。Jest 等待 Promise 链完成,然后再结束测试。如果 Promise 以拒绝状态结束,则 Jest 无法通过测试。

test("element does not have slds-icon class when bare", () => {
  const element = createElement("one-primitive-icon", { is: PrimitiveIcon });
  document.body.appendChild(element);
  // Property value is assigned after the component is inserted into the DOM
  element.variant = "bare";

  // Use a promise to wait for asynchronous changes to the DOM
  return Promise.resolve().then(() => {
    expect(element.classList).not.toContain("slds-icon");
  });
});

调用将组件插入到 DOM 和生命周期钩子中,然后被调用。然后,该示例在调用后设置元素值,这类似于将组件插入 DOM 后由另一个方法或用户交互设置属性的情况。在这些情况下,请使用 promise 等待异步 DOM 更新。有关组件生命周期和呈现的更多信息,请参见生命周期流。appendChild()connectedCallback()renderedCallback()appendChild()

如果在调用之前设置了该属性,则会同步呈现组件。在调用之前设置该属性时,无需等待异步更新或返回 promise。appendChild()appendChild()

为使用 Wire Service 的 Lightning Web 组件编写 Jest 测试

组件使用线路服务从 Salesforce 获取数据。若要测试这些组件如何处理来自线路服务的数据和错误,请使用测试实用程序。@salesforce/sfdx-lwc-jest

测试使用的输入不应依赖于外部代码或数据,您必须对其进行完全控制。从中导入测试实用程序 API 以模拟数据,以便测试不依赖于远程调用或服务器延迟等不可预测因素。sfdx-lwc-jest

该实用程序有三个适配器用于模拟线路服务数据:通用线路适配器、Lightning 数据服务 (LDS) 线路适配器和 Apex 线路适配器。sfdx-lwc-jest

  • 调用 API 时,通用适配器会按需发出数据。它不包含有关数据本身的任何额外信息。emit()
  • LDS 适配器模拟 Lightning 数据服务行为,并包含有关数据属性的信息。
  • Apex 线路适配器模拟对 Apex 方法的调用,并包含任何错误状态。

注意

如果您未使用该实用程序来使用 Salesforce DX,则可以使用测试实用程序导入适配器。但是,我们建议使用集成开发体验。sfdx-lwc-jest@salesforce/wire-service-jest-utilsfdx-lwc-jest

若要控制测试,请创建一个 JSON 文件来定义组件所需的数据,而不是从 Salesforce 获取数据。

若要使用线路服务测试实用程序,请按照以下高级步骤操作。

  1. 在组件包中,创建一个名为 的文件夹和一个名为 的 JavaScript 类。最佳做法是以组件命名文件,后跟 .__tests__componentName.test.js.test.js
  2. 在文件夹中,创建一个文件夹和一个名为 .__tests__data_wireAdapter_.json
    1. 在 JSON 文件中,模拟电线适配器发出的数据。
    2. 如果有线适配器是 LDS 有线适配器,请使用访问有线适配器所基于的 UI API 的 REST 客户端获取数据快照。这种方法比手动编写 JSON 更准确。
  3. 在文件中:componentName.test.js
    1. 导入被测元件及其电线适配器。测试必须引用与被测组件相同的电线适配器。
    2. 从 JSON 文件导入模拟数据。
    3. 发出模拟数据。
    4. 验证组件是否收到了模拟数据。

被测组件

我们的示例组件是产品卡组件。

产品卡组件显示产品及其名称。

<!-- productCard.html -->
<template>
  <div class="content">
    <template lwc:if={product}>         
        <div class="name">         
          <div>Name:</div>
          <div>{name}</div>
        </div>
    </template>
  </div>
</template>

在组件的 JavaScript 文件中,修饰器指示线路服务使用线路适配器来设置记录数据。它装饰函数,该函数接收具有错误或数据属性的对象。@wiregetRecordwiredRecord

// productCard.js
import { LightningElement, wire } from "lwc";

// Wire adapter to load records.
import { getRecord } from "lightning/uiRecordApi";

export default class ProductCard extends LightningElement {
  // Id of Product__c to display.
  recordId;

  // Product__c to display
  product;

  // Product__c field values to display
  name = "";

  @wire(getRecord, { recordId: "$recordId", fields: ["Product.Name"] })
  wiredRecord({ data }) {
    if (data) {
      this.product = data;
      this.name = data.fields.Name.value;
    }
  }
}

提示

lwc-recipes 存储库提供了使用有线服务的几个组件的示例,其中包括 Jest 测试。

模拟数据

在文件夹中,创建一个名为 的文件夹。在文件夹中,创建一个名为 的文件,该文件与电线适配器同名。定义组件期望从服务器获得的数据。您可以自己编写 JSON,但这可能会变得困难且容易出错。最佳做法是使用访问 UI API 的 REST 客户端获取数据快照。例如,此数据是来自 的响应,该响应是支持电线适配器的资源。__tests__datadatagetRecord.json/ui-api/records/{recordId}getRecord

我们的模拟数据仅定义记录中的字段。在实际测试中,模拟组件所需的所有数据。Name

{
  "fields": {
    "Name": {
      "value": "DYNAMO X1"
    }
  }
}

创建 JavaScript 测试

单元测试检查产品卡是否显示产品名称。

测试必须导入被测组件中使用的电线适配器。在这里,这是模块中的电线适配器。测试还必须导入模拟数据以通过电线适配器发送。getRecordlightning/uiRecordApi

该测试创建组件并将其附加到 DOM。仅当组件连接到 DOM 时,组件才会接收有关数据的更新。组件连接后,将模拟数据传递给电线适配器上的函数。emit

发出模拟数据后,if 或 change 组件将重新呈现。解析 promise 以确保测试代码在 DOM 更新为新数据后运行。该代码验证模拟数据中的产品名称字段是否在 DOM 中正确输出。productname

// productCard.test.js
import { createElement } from "lwc";
import ProductCard from "c/productCard";
import { getRecord } from "lightning/uiRecordApi";

// Import mock data to send through the wire adapter.
const mockGetRecord = require("./data/getRecord.json");

test("displays product name field", () => {
  const element = createElement("c-product_filter", { is: ProductCard });
  document.body.appendChild(element);

  // Emit mock record into the wired field
  getRecord.emit(mockGetRecord);

  // Resolve a promise to wait for a rerender of the new content.
  return Promise.resolve().then(() => {
    const content = element.shadowRoot.querySelector(".content");
    const nameField = mockGetRecord.fields.Name.value;
    expect(content.textContent).toBe(`Name:${nameField}`);
  });
});

注意

在 Spring ’21 及更早版本中,您必须注册正在测试的电线适配器。该代码仍然有效,但不建议这样做。

DOM 检查测试可能会发生变化

Lightning Experience 中 HTML、CSS 和 DOM 的内容和结构可能随时更改,不能被视为稳定的 API。使用 Selenium WebDriver 等工具进入组件内部的 UI 测试需要持续维护。

Salesforce 从不保证向后兼容 HTML、CSS 或 DOM。我们指出,随着 Lightning Experience 随着现代 Web 标准的发展而不断变化,这些测试的脆弱性。我们了解您从自动化 UI 测试中获得的价值,以及由此给您带来的维护负担。

Lightning Web 组件基于 Web 组件标准。该标准包括 Shadow DOM,它对其他组件隐藏组件的标记、样式和行为。这种封装给 UI 测试带来了挑战,尤其是依赖于全局搜索 DOM 或进入自定义元素内部的测试。

该属性封装元素的 DOM 子树。这在 DOM 中表示为 一个。 这个 DOM 子树中的元素不能通过传统的 DOM 查询方法获得。由 Lightning Web 组件呈现的元素包含此新属性,并且这些元素在正常的 DOM 查询中是隐藏的。shadowRootshadowRootDocumentFragmentshadowRoot

我们建议使用 Jest 对单个 Lightning Web 组件进行单元测试。

仅将 Selenium WebDriver 等 UI 测试工具用于端到端测试。

开玩笑测试

要为 Lightning Web 组件编写单元测试,请使用 sfdx-lwc-jest。

在 Jest 测试上下文中,代码可以使用被测元素的属性来访问影子树。该属性封装元素的影子树。shadowRootshadowRoot

此代码在“示例”部分访问组件的影子树。<div><lightning-lwc-parent>

const element = createElement("c-lightning-lwc-parent", { is: LightningLwcParent });
document.body.appendChild(element);
const div = element.shadowRoot.querySelector(".in-the-shadow");

Selenium WebDriver 测试

对于端到端 UI 测试,请调整现有测试以使用 Shadow DOM。调整测试因工具而异,策略也在迅速发展。本文是 Selenium WebDriver 的一个很好的例子。

正如本文所讨论的,全局查询通过失败。要在 Lightning Web 组件的影子树中查找元素,请在客户端上执行 JavaScript 以查询组件的属性。WebDriver.findElement()shadowRoot

注意

本文有一个屏幕截图,显示了 Chrome 开发者工具中的 DOM 元素。屏幕截图显示了一个文档片段,它是组件影子树的顶部节点。如果您在 Chrome 开发者工具中查看 Lightning Web 组件,则看不到 因为 LWC 使用影子 DOM polyfill。Salesforce 支持某些未实现 Shadow DOM Web 标准的浏览器。polyfill 在这些浏览器中提供了一个影子 DOM。要在页面上查找 Lightning Web 组件,请查找包含连字符的元素名称。选择元素并在控制台中运行。Lightning Web 组件返回 .#shadow-root#shadow-root$0.shadowRoot#document-fragment

Jest 测试模式和模拟依赖关系

在使用 Jest 进行测试时,请遵循这些模式和做法来隔离行为并最大限度地提高单元测试的效率。

测试属性更改

让我们从一个简单的属性更改开始。属性更改时的组件重新渲染是异步的,因此向 DOM 添加某些内容的顺序并不总是可预测的。我们建议您在检查预期行为之前,等待值更改反映在 DOM 中。一种技术使用语句在页面元素更改后检查值,如下所示:Promise.resolve()

  1. 将组件添加到 DOM。
  2. 更改属性值。
  3. 等待组件通过返回值重新呈现。Promise.resolve()
it("Renders with Hello Matt", () => {
  const element = createElement("c-hello-component", {
    is: HelloComponent,
  });
  document.body.appendChild(element);

  element.person = "Matt";

  return Promise.resolve().then(() => {
    const pTag = element.shadowRoot.querySelector("p");
    expect(pTag.textContent).toEqual("Hello, Matt!");
  });
});

提示

有关更多信息,请参阅 Matt Goldspink 在 Vlocity 撰写的博客文章 Testing Lightning Web Components。

使用属性测试组件

为了扩展我们的示例,让我们添加一个属性。属性允许您在测试中更改一个值,以查看更改的呈现方式。使用语句在调用之前设置属性,例如:Object.assign()appendChild

Object.assign(element, attributes);
document.body.appendChild(element);

例如,让我们将初始测试中的背景颜色设置为红色:

it("Renders with Hello Matt", () => {
  const element = createElement("c-hello-component", {
    is: HelloComponent,
  });
  Object.assign(component, { backgroundColor: "red" });
  document.body.appendChild(element);

  element.person = "Matt";

  return Promise.resolve().then(() => {
    const pTag = element.shadowRoot.querySelector("p");
    expect(pTag.textContent).toEqual("Hello, Matt!");
  });
});

嘲笑

单元测试可能涉及的不仅仅是对简单 UI 元素的更新。某些代码依赖于某些依赖项的行为,例如导入的模块、基本 Lightning 组件和事件处理程序。但是,您希望您的代码处于一致的环境中,不受服务器调用、数据库请求或远程访问 API 的可变行为和计时的影响。以下部分包括有关单元测试的这些依赖项的模拟行为的指南。模拟是一种常见的测试做法,用于隔离正在测试的代码的行为。

基本 Lightning 组件

Salesforce 在 sfdx-lwc-jest 存储库中提供了模拟组件,您可以在 lightning-stubs 目录中找到这些组件的源代码。将这些模拟组件用于包含基本 Lightning 组件的测试。模拟组件与实际组件的 API 匹配,但不具备所有功能,因此它们可以作为测试的良好资源。即使这些模拟组件不会触发任何事件,您仍然可以调用其事件处理程序。

例如,查看 lwc-recipes 存储库中的 miscToastNotification.js 示例。为了模拟用户输入,常量引用了 sfdx-lwc-jest 提供的模拟元素。我们仍然可以在 DOM 中查询它,并从中调度一个事件来调用我们连接到它的处理程序。我们使用一个模拟组件来保持对输入值的控制,因为我们只想测试通知的行为。inputTitleEl<lightning-input>change

// Select input field for simulating user input
const inputMessageEl = element.shadowRoot.querySelector('lightning-input[data-id="messageInput"]');
inputMessageEl.value = TOAST_MESSAGE;
inputMessageEl.dispatchEvent(new CustomEvent("change"));

在使用我们的模拟组件时,请记住以下几点。

  • 我们建议您的测试不要依赖于插槽的呈现顺序。例如,假设有两个命名槽:和 。如果存在预期内容,则即使模拟(或真实)组件交换了这些插槽的呈现顺序,测试也会通过。actionstodos
  • 基本 Lightning 组件具有一些属性,这些属性不会反映为 DOM 中的属性。例如,您可以设置属性 ,该属性用于确定要用于按钮的 SLDS 类,而不是呈现的值。设计测试用例以考虑此行为,并且不要假定所有属性都反映为属性。<lightning-button>iconPosition
  • 这些模拟不会触发任何事件,但您可以调用它们。dispatchEvent()

事件处理程序

查看相同的 miscToastNotification.js 示例,也可以看到一个模拟事件处理程序。此测试定义多个常量值,然后触发事件,将常量插入元素中。ShowToastEventNamejest.fn()lightning-input

const TOAST_TITLE = "The Title";
const TOAST_MESSAGE = "The Message";
const TOAST_VARIANT = "warning";

// Create initial element
const element = createElement("c-misc-toast-notification", {
  is: MiscToastNotification,
});
document.body.appendChild(element);

// Mock handler for toast event
const handler = jest.fn();
// Add event listener to catch toast event
element.addEventListener(ShowToastEventName, handler);

在测试结束时,验证事件处理程序是否按预期调用,以及是否使用正确的参数。

return Promise.resolve().then(() => {
  // Check if toast event has been fired
  expect(handler).toHaveBeenCalled();
  expect(handler.mock.calls[0][0].detail.title).toBe(TOAST_TITLE);
  expect(handler.mock.calls[0][0].detail.message).toBe(TOAST_MESSAGE);
  expect(handler.mock.calls[0][0].detail.variant).toBe(TOAST_VARIANT);
});

模块导入

若要创建对模拟组件的引用以更好地控制组件行为,请在文件中添加 moduleNameMapper 设置。要查看示例,请查看 lwc-recipes 存储库中的 jest.config.js 如何引用一些带有模块名称的模拟组件。jest.config.js

const { jestConfig } = require("@salesforce/sfdx-lwc-jest/config");
module.exports = {
  ...jestConfig,
  moduleNameMapper: {
    "^@salesforce/apex$": "<rootDir>/force-app/test/jest-mocks/apex",
    "^lightning/navigation$": "<rootDir>/force-app/test/jest-mocks/lightning/navigation",
    "^lightning/platformShowToastEvent$":
      "<rootDir>/force-app/test/jest-mocks/lightning/platformShowToastEvent",
    "^lightning/uiRecordApi$": "<rootDir>/force-app/test/jest-mocks/lightning/uiRecordApi",
  },
};

现在,让我们看看如何在 lwc-recipes 存储库的 miscToastNotification.test.js 中使用此配置。它有一个声明:import

import { ShowToastEventName } from "lightning/platformShowToastEvent";

如果没有该条目,此语句将解析为存根 https://github.com/salesforce/sfdx-lwc-jest/blob/master/src/lightning-stubs/platformShowToastEvent/platformShowToastEvent.js。moduleNameMapperimport

使用该条目时,此语句解析为 jest-mocks 自定义存根 https://github.com/trailheadapps/lwc-recipes/blob/master/force-app/test/jest-mocks/lightning/platformShowToastEvent.js。模拟存根具有向事件对象添加其他属性的自定义逻辑。moduleNameMapperimport

注意

如果使用自定义选项覆盖缺省文件,请将这些值与 中定义的值合并。jest.config.jssetupFilesAfterEnv@salesforce/sfdx-lwc-jest/config

@salesforce范围的导入

在测试环境中,组件可能无权访问生产架构。导入对命名空间的引用时,请在测试期间将返回值模拟为占位符。

在 Jest 测试中,我们使用 jest-transformer 将 import 语句转换为变量声明。该值设置为标签路径。默认情况下,分配的字符串值为 。您可以使用为导入提供自己的值。此示例返回字符串而不是 。@salesforce/labelmyImportc.specialLabeljest.mock()value set in testc.specialLabel

import myImport from "@salesforce/label/c.specialLabel";

jest.mock(
  "@salesforce/label/c.specialLabel",
  () => {
    return { default: "value set in test" };
  },
  { virtual: true },
);

寻找更多示例?

请参阅 lwc-recipes 存储库的 lwc 目录。许多食谱都有一个目录,其中包含注释的 jest tests。__tests__

提高性能

启用 CDN 和安全浏览器缓存以提高应用程序性能。

注意

每天第一次加载组件时,加载速度会变慢,因为该组件未缓存。在后续加载时,组件的加载和显示速度更快。

启用安全浏览器缓存

在浏览器中启用安全数据缓存,通过避免与服务器的额外往返来提高页面重新加载性能。

默认情况下,此设置处于选中状态。

注意

禁用安全和持久的浏览器缓存会对 Lightning Experience 的性能产生重大负面影响。仅在这些情况下禁用。

  • 公司的策略不允许浏览器缓存,即使数据已加密也是如此。
  • 在沙盒或 Developer Edition 中进行开发时,您希望在不清空安全缓存的情况下查看任何代码更改的效果。
  1. 在“设置”中,输入“快速查找”框,然后选择“会话设置”。Session
  2. 选中“启用安全且持久的浏览器缓存以提高性能”复选框。
  3. 点击保存

使 CDN 能够更快地加载应用程序

通过启用 Akamai 的内容分发网络 (CDN) 为 Lightning 组件框架提供静态内容,更快地加载 Lightning Experience 和其他应用程序。CDN 通常会加快页面加载时间,但它也会更改提供文件的源域。如果您的公司对 Salesforce 提供的内容有 IP 范围限制,请在启用此设置之前进行全面测试。

CDN 通过将缓存版本存储在多个地理位置来缩短静态内容的加载时间。此设置为 Lightning 组件框架中的静态 JavaScript 和 CSS 启用 CDN 交付。它不会在 CDN 中分发您的 Salesforce 数据或元数据。

默认情况下,对于在 Winter ’19 版本之前创建的组织,此设置处于禁用状态,默认情况下,对于新组织以及所有新的和现有的 Experience Builder 站点,此设置处于禁用状态。适用于 Experience Builder 站点的 Lightning CDN 无法关闭且不可配置。

  1. 在“设置”中,输入“快速查找”框,然后选择“会话设置”。Session
  2. 选中“为 Lightning 组件框架启用内容分发网络 (CDN)”复选框。
  3. 点击保存。如果您遇到任何问题,请询问您的网络管理员贵公司的防火墙是否阻止了任何 Akamai CDN 内容。确保将其添加到贵公司运营的任何允许列表或防火墙中。您可以 ping 操作,但不能直接浏览到 位于 的根 URL。https://static.lightning.force.comstatic.lightning.force.comhttps://static.lightning.force.com重要不要使用 IP 地址进行网络过滤,因为这可能会导致 的连接问题。的 IP 地址是动态的,不会在 Salesforce 的允许的 IP 地址列表中进行维护。https://static.lightning.force.comhttps://static.lightning.force.com

调试 Lightning Web 组件

Lightning Web 组件使用标准 HTML 和 JavaScript 构建,在桌面上,它们在各种受支持的浏览器中运行。您可以使用标准浏览器和 JavaScript 调试工具(如 Chrome DevTools)在开发过程中调试组件。若要查看特定于移动设备的功能,请使用移动设备或虚拟设备内部版本。

在开发过程中运行和调试组件的最简单方法是创建一个 Lightning 页面并将您的组件添加到其中。然后在您喜欢的浏览器中加载 Lightning 页面,并使用您喜欢的检查和调试工具。LWC 调试针对 Chrome DevTools 进行了优化。

注意

此内容改编自 Salesforce 首席开发人员布道师 René Winklemeyer 的博客文章调试您的 Lightning Web 组件

Lightning 组件的执行模式

Lightning 组件框架以以下两种模式之一执行:生产模式和调试模式。

让我们看一下执行模式之间的差异。

生产模式

默认情况下,框架在生产模式下运行。此模式针对性能进行了优化。

在生产模式下,JavaScript 代码经过优化和“缩小”,以将代码的大小减小到尽可能少的字节。生产模式删除了换行符、空格、制表符和代码注释,并缩短了函数和变量的名称。由于此过程,提供给浏览器的 JavaScript 代码被模糊处理。

注意

缩小是性能优化,而不是知识产权保护。缩小的代码很难阅读,但未加密或以其他方式阻止查看。

在生产模式下可见的代理对象

生产模式还对某些事情使用 JavaScript 代理,例如通过装饰器 、 和 提供的数据。和修饰属性被视为只读属性。通过使用 JavaScript 代理,框架可以确保无法修改这些属性。对于修饰的属性,框架使用代理来观察数据突变,以便它可以对更改做出反应。在生产模式下进行调试时,你看到的是代理对象,而不是你感兴趣的对象。@api@wire@track@api@wire@track

Lightning Locker 和 Lightning Web Security 在标准 Web API 上使用代理对象来防止对 DOM 中的全局对象进行更改。

生产模式调试

您可以使用 Chrome DevTools 中的“漂亮打印”选项在生产模式下获得最少的代码格式。单击“源”面板底部的漂亮打印图标以打开应用了格式的新选项卡。{}

由于变量和函数的名称已更改,代码仍然不完全可读,但对于第一次检查来说是很好的。您可以在 Chrome DevTools 中设置断点、检查值以及使用调试器。

以下是默认情况下在生产模式下看到的内容,使用 lwc-recipes 中的示例代码。在此示例中,第 1 行延伸超过 1200 个字符。

以下是选择“漂亮的打印件”后在生产模式下看到的内容。

调试模式

在调试模式下,JavaScript 代码更易于阅读和调试。在 DevTools 中看到的 JavaScript 源代码与未编译的源代码类似。调试模式还为某些警告和错误添加了更详细的输出。

组件代码在生产模式和调试模式下编译。在调试模式下,编译的 JavaScript 代码不会优化或缩小。LWC 编译器可以生成支持更高级调试功能的信息。

为用户帐户启用调试模式后,您会看到这些更改。

  • 顶部会出现一个横幅,提醒您调试模式已打开,并且会减慢速度。
  • “体验页面时间 (EPT)”指标显示在页眉中。它以绿色、橙色或红色显示,以指示页面加载时间的运行状况。
  • 页眉中的存储指标显示页面存储的千字节数据,以指示内存使用情况和缓存。该指标以绿色、橙色或红色进行类似的颜色编码。

我们在生产模式下看到的相同的 lwc-recipes 示例代码,在启用调试模式时未缩小时,看起来不那么神秘。它更具可读性,并显示函数和变量的名称。

在 Salesforce 中启用调试模式

启用调试模式,以便更轻松地调试 JavaScript 代码。仅对主动调试 JavaScript 的用户启用调试模式。对于启用了调试模式的用户,Salesforce 速度较慢。

要为组织中的用户启用调试模式,请执行以下操作:

  1. 在 Salesforce 中,从“设置”中输入“快速查找”框,然后选择“调试模式用户”。Debug Mode启用了调试模式的用户在“调试模式”列中有一个复选标记。
  2. 在用户列表中,找到需要启用调试模式的任何用户。如有必要,请使用标准列表视图控件来筛选组织的用户。
  3. 选中要为其启用调试模式的用户旁边的复选框。
  4. 单击启用

提示

如果在 JavaScript 文件中只看到几行代码,则未启用调试模式。如果启用调试模式无法重置代码编辑器中的代码,请执行硬重新加载。打开 DevTools 后,右键单击浏览器的“重新加载”按钮,然后单击“硬重新加载”。

若要为用户禁用调试模式,请按照上述步骤操作,然后单击“禁用”而不是“启用”。

在开发过程中禁用缓存

在沙盒或 Developer Edition 组织中禁用安全和持久的浏览器缓存设置,以便在不清空缓存的情况下查看任何代码更改的效果。

缓存设置通过避免与服务器的额外往返来提高页面重新加载性能。

警告

禁用安全和持久的浏览器缓存会对 Lightning Experience 的性能产生重大负面影响。始终在生产组织中启用该设置。

  1. 在“设置”中,输入“快速查找”框,然后选择“会话设置”。Session
  2. 取消选中“启用安全且持久的浏览器缓存以提高性能”复选框。
  3. 点击保存

禁用浏览器缓存设置后,您可以重新加载页面以测试代码更改,而无需清除缓存。我们建议您在调试代码后重新启用浏览器缓存设置。

使用 Chrome DevTools 进行调试

要调试 Lightning Web 组件代码,请使用 Chrome DevTools。

Google Chrome 包含一整套出色的 Web 开发工具,即 Chrome DevTools。这些工具非常适合调试 Lightning Web 组件。

首先,加载可以运行 Lightning 组件的最简单页面。然后打开 DevTools。

  • 在 Windows 和 Linux 上,在 Google Chrome 浏览器中按下 Control-Shift-I。
  • 在 Mac 上,按下 Option-Command-I。
  • 在任何平台上,按 F12 或在页面中单击鼠标右键,然后选择“检查”。

若要快速查找失败的代码行,请在“源”面板中启用“DevTools 调试器面板中的”暂停所有异常“选项,然后再运行代码。

当您启用异常暂停时,浏览器会在由 Salesforce 代码、其他库代码和组件代码引起的异常时停止。组件引发的异常可能会在框架代码中被捕获。

要了解有关在 Google Chrome 上调试 JavaScript 的更多信息,请参阅 Google Chrome DevTools 网站。

请查看 Trailhead 上的 Lightning Web 组件故障排除,了解将 Chrome DevTools 与 Lightning Web 组件结合使用的分步说明。

在“源”面板中查找代码

在 Chrome DevTools 的“源”面板中,在文件夹的“页面”窗格中找到您的 Lightning Web 组件代码。在这里,您可以看到默认命名空间文件夹中的组件。lightning/n/modulesc

提示

有关在启用 LWS 的情况下进行调试的信息,请参阅在启用了 LWS 的组织中调试组件。

启用自定义格式化程序

启用自定义格式化程序时,可以使用更多调试功能。

在 Chrome DevTools 中,选择“设置”() |首选项 |控制台 |启用自定义格式化程序

Lightning Web 组件的自定义格式化程序允许您查看代理对象中包含的实际值。虽然在调试时看不到代理对象,但它们仍然存在并阻止修改。自定义格式化程序可以在不删除代理的情况下查看代理。

提示

如果在组织中启用了 Lightning Web Security,则自定义格式化程序还允许您在 DevTools 控制台中查看其他消息和筛选的调用堆栈。请参阅在启用了 LWS 的组织中调试组件。

来自 LWC 引擎的控制台警告

在调试模式下,Lightning Web 组件引擎会识别仅在运行时才能检测到的不良模式,并将其打印为控制台警告。

最佳做法是使用调试模式在组织中开发 Lightning Web 组件。您可以在开发时使用 LWC 引擎的反馈来改进代码。

仅筛选您自己的组件的一种方法是删除“info”日志级别以隐藏堆栈跟踪。

调试线适配器

使用调试模式对具有未缩小的 JavaScript 和自定义格式的电线适配器进行故障排除。

调试电线适配器的最简单方法是通过 Chrome DevTools。

调试电线适配器:

  1. 启用调试模式。
  2. 在 Chrome DevTools 中,启用自定义格式化程序。

当您通过 接收数据时,您的数据将绑定到函数或属性。@wire

检查有线功能

如果使用有线函数,则可以根据 Chrome DevTools 的 Sources 面板中的解构和属性进行调试。dataerror

或者,您可以使用下一节中介绍的方法调试有线函数。

检查有线属性或方法

如果在组件上使用有线属性或方法,则可通过自定义对象格式化程序获取调试信息。

每个有线属性或方法都返回具有以下形状的信息:

  • data– 电线适配器返回的最后一个值
  • config– 报告给电线适配器的最后一个配置
  • context– 仅适用于上下文线适配器
  • isDataProvisionedForConfig– 一个布尔值,用于返回线路适配器配置的数据是否与配置相对应。如果报告了配置,则返回 .true

提示

lwc-recipes 存储库具有使用有线属性的 apexWireMethodToProperty 组件。

使用或检查呈现的 LWC 自定义元素检查组件实例。例如,单击 Chrome DevTools 的“元素”面板中的元素。this<c-apex-wire-method-to-property>

单击该元素后,打开“控制台”面板并输入 $0 以返回调试信息。

在启用了 LWS 的组织中调试组件

当您在启用了使用 Lightning Web Security 的组织中调试 Lightning Web 组件时,您会注意到与未启用 Lightning Web Security 的组织相比存在一些差异。

首先,确保启用调试模式以获得最佳调试体验。

对于由 LWS 沙盒处理的代码,调试技术通常是相同的,但让我们来看看一些差异。

LWS 下 LWC 调试的源代码位置

从 24 年冬季开始,当您使用 Chrome DevTools 调试 Lightning Web 组件时,您的组件源代码将显示在文件夹内的“源”面板中。此位置在“源”面板中的“查找代码”中进行了介绍。无论启用 Lightning Locker 还是 LWS,位置都是相同的。lightning/n/modules

以前,当您的 Lightning Web 组件在启用了 Lightning Web Security 的组织中运行时,一个特殊的文件夹会将您的组件文件单独组织在命名空间文件夹下。lws

在这里,您可以在当前页面上看到命名空间及其组件。启用了 LWS 的文件与源映射一起显示。ccompositionBasics.js

源代码映射使沙盒代码看起来与组件的原始源代码相似。您可以检查它、使用断点等。您必须启用调试模式才能查看源映射并启用断点。

提示

如果“源”面板中的代码看起来与您的原始源代码不同,请确保已启用在 Chrome DevTools 中启用 JavaScript 源映射设置。默认情况下,它处于启用状态。

如果已在调试器中,还可以在“页面”窗格中找到源文件。右键单击并选择在边栏中显示

此处,调试器停止,但未在侧边栏中选择该文件。当您选择“在边栏中显示”时,将选择正确的文件。compositionContactSearch.js

LWS 下 Aura 组件调试的源码位置

调试 Aura 组件时,源代码将显示在“源”面板中,该子文件夹位于以组织命名的文件夹内。lightning/n/components

文件夹的确切位置可能因浏览器和会话而异,还取决于您使用组件的方式。如果您没有立即看到该文件夹,请展开节点,直到找到它。lightning/n/components

此示例显示了 lwc-recipes 中的 Aura Interop 组件。顶部文件夹名称与包含该组件的 Lightning 页面的名称匹配。突出显示的文件用于调试。Aura_Interoperability

控制台堆栈跟踪

控制台中的堆栈跟踪显示会过滤掉 LWS 调用,以便更清楚地了解组件中的错误。LWS 调用包含在其自己的文件夹 (1) 中。

若要查看筛选的堆栈跟踪,请启用自定义格式化程序,如启用自定义格式化程序中所述。

控制台消息

控制台消息在控制台方法(如 和 )中显示有关 LWS 的信息。例如,当在沙盒的一侧而不是另一侧跟踪对象突变时调用。console.warnconsole.infoconsole.warn

要查看 LWS 控制台消息,请启用自定义格式化程序,如启用自定义格式化程序中所述。

注意

LWS 更改控制台消息的源代码行号和源代码文件。控制台消息似乎来自 Salesforce 文件,而不是来自记录消息的组件的 JavaScript 文件。此行为是由于浏览器实现导致的已知问题,因此我们正在等待浏览器供应商实现修复。aura_proddebug.js

调试移动组件

您可以使用 Chrome DevTools 中的设备模式等工具,在桌面浏览器中测试移动基础知识,例如小屏幕尺寸和响应式设计。要查看特定于移动设备的功能,请在真实移动设备上使用 Salesforce Mobile 应用程序。

借助 Lightning 移动版,桌面版和移动版 Salesforce 提供相同的用户界面:Lightning Experience。这意味着,虽然它不能替代在实际移动设备上进行全面测试,但您可以使用桌面浏览器来运行和调试移动 Lightning 应用程序和组件的许多方面。

借助 Chrome DevTools 设备模式,您可以模拟移动设备的以下方面:

  • 屏幕尺寸
  • 设备方向
  • 位置更改
  • 移动设备 CPU 限制
  • 无线网络限制

要了解有关设备模式的更多信息,请参阅 Google Chrome DevTools 网站上的在 Chrome DevTools 中使用设备模式模拟移动设备。

将 Aura 组件迁移到 Lightning Web 组件

Aura 组件和 Lightning Web 组件可以存在于同一个应用程序中。本部分通过将概念从 Aura 组件映射到 Lightning Web 组件,帮助您迁移组件并应用现有技能。

有关如何将概念从 Aura 组件映射到 Lightning Web 组件的图形说明,请参阅此 Medium 帖子。

适用于 Aura 开发人员的 Lightning Web 组件 Trailhead 模块是帮助您了解 Lightning Web 组件的另一个资源。

迁移策略

Lightning Web 组件的编程模型与 Aura 组件的模型根本不同。迁移组件不是逐行转换,这是重新审视组件设计的好机会。在迁移 Aura 组件之前,请评估组件的属性、接口、结构、模式和数据流。

最容易迁移的组件是仅呈现 UI 的简单组件。通过迁移更大的组件树(组件中的组件)而不是单个组件,您可以获得更高的性能和开发人员的工作效率。但是,迁移一个组件并查看 Aura 编程模型中的概念如何映射到 Lightning Web 组件编程模型中的概念是一种有用的学习体验。

迁移一个组件后,你将能够更好地确定你和你的组织是否有必要:

  • 进行更大规模的迁移工作
  • 仅将 Lightning Web 组件用于新组件
  • 暂时坚持使用 Aura 组件

选择权由您决定,每个人的选择都不同,具体取决于用例和可用资源。无论您做出什么决定,迁移组件都是一项有价值的学习练习。

选择要迁移的组件

要决定是否迁移组件,首先要了解 Aura 组件和 Web 组件如何协同工作,然后评估组件的使用方式和位置。

在选择要迁移的组件之前,请确保您了解 Aura 组件中的分面概念。

让我们回顾一下有关 Lightning Web 组件和 Aura 组件如何协同工作的最重要的事实。

  • Lightning Web 组件和 Aura 组件可以在同一运行时中共存。
  • Aura 组件可以包含 Lightning Web 组件。
  • Lightning Web 组件不能包含 Aura 组件。
  • 如果 Aura 组件具有包含其他 Aura 组件的 face,则您也必须迁移这些其他 Aura 组件。

迁移组件包文件

Aura 编程模型与 Lightning Web 组件编程模型的组件包文件结构不同。

以下是文件在两个编程模型之间的映射方式。

资源Aura 文件闪电网络组件文件另见
标记sample.cmpsample.html组件 HTML 文件
控制器sampleController.jssample.js组件 JavaScript 文件
助手sampleHelper.jssample.jsLightning 组件开发人员指南:帮助程序
渲染sampleRenderer.jssample.jsLightning 组件开发人员指南:渲染器
CSS的sample.csssample.css组件 CSS 文件
文档sample.auradoc目前不可用Lightning 组件开发人员指南:组件文档
设计sample.designsample.js-meta.xml组件配置文件
SVGsample.svg目前不可用Lightning 组件开发人员指南:自定义图标

注意

Aura 组件中的控制器、帮助程序和渲染器文件映射到 Lightning Web 组件中的一个 JavaScript 文件。

迁移标记

Aura 文件包含标记,包括特定于 Aura 的标签。让我们看看此标记如何映射到 Lightning Web 组件中的等效概念。.cmp

迁移属性

将属性从 Aura 组件中的标签迁移到 Lightning Web 组件中的 JavaScript 属性。<aura:attribute>

让我们看一下 Aura 组件中的属性。myAttribute

<aura:component>
  <aura:attribute name="myAttribute" default="Hello" />
</aura:component>

在 Lightning Web 组件中,我们改用名为 JavaScript 的属性。myAttribute

// myComponentName.js
import { LightningElement, api } from "lwc";
export default class MyComponentName extends LightningElement {
  @api myAttribute = "Hello";
}

修饰器定义为公共属性。请参阅公共属性。@apimyAttribute

引用组件的 HTML 文件中的属性。

<!-- myComponentName.html -->
<template> {myAttribute} </template>

Lightning Web 组件中的布尔属性值是在标记中设置的,没有指示和值。该值由属性的存在 () 或不存在 () 设置。在 JavaScript 中,可以使用动态计算值设置布尔属性值。如果布尔属性的值计算为 ,则会将其从 DOM 中删除。请参见布尔属性。 truefalsetruefalsefalse

重要

Lightning Web 组件必须完全支持转换后的 Aura 组件的属性。如果没有,则会出现错误和破损。

迁移迭代

将 Aura 组件中的标签迁移到 Lightning Web 组件中。<aura:iteration>for:each

下面是 Aura 语法。

<aura:iteration items="{!v.items}" itemVar="item"> {!item} </aura:iteration>

下面是 Lightning Web 组件语法。

<template for:each={items} for:item="item">
  <p key={item.id}>{item}</p>
</template>

请注意,必须使用 a 为列表中的每个项目分配唯一值。请参阅渲染列表。key

您无法像在 Aura 组件标记中那样初始化 Lightning Web 组件模板中的列表选项。您必须在 JavaScript 中初始化列表选项。有关示例,请参阅 lightning-dual-listbox 组件。

迁移条件语句

将 Aura 组件中的标签迁移到 、 和 Lightning Web 组件中的标签。<aura:if>lwc:iflwc:elseiflwc:else

下面是 Aura 组件中的语法。

<aura:if isTrue="{!v.something}">
  <div>Conditional Code</div>
  <aura:set attribute="else">
    <div>Conditional Code</div>
  </aura:set>
</aura:if>

下面是 Lightning Web 组件中的语法。

<template>
  <div lwc:if={something}>Conditional Code</div>
  <div lwc:elseif={something}>Conditional Code</div>
</template>
import { LightningElement } from "lwc";
export default class MyComponentName extends LightningElement {
  something = true;
}

迁移表达式

将表达式从 Aura 组件中的标记迁移到 Lightning Web 组件中的 JavaScript。

下面是 Aura 组件中的语法。

<aura:if isTrue="{! (!v.something ? v.optionA : v.optionB) }">
  <div>Conditional Code</div>
</aura:if>

在 Lightning Web 组件中,使用表达式并将其移动到 JavaScript 中。现在代码可以进行单元测试,这是一件非常非常好的事情。下面是 HTML 文件。lwc:if

<template>
  <div lwc:if={condition}>Conditional Code</div>
</template>

提示

Lightning Web 组件的 HTML 文件中的动态内容在 getter 引用周围没有引号,也没有感叹号或值提供程序 () 语法。不要使用 Aura 组件中的表达式语法,即使您的手指可能习惯于键入它!v.

下面是 Aura 组件中的表达式。

<aura:if isTrue="{!v.condition}">

下面是 Lightning Web 组件中的类似 HTML。

<div lwc:if={condition}>Conditional Code</div>

下面是 JavaScript 文件。

import { LightningElement } from "lwc";
export default class MyComponentName {
  get condition() {
    return something ? true : false;
  }
}

迁移全球价值提供商

将 Aura 组件中的全局值提供程序迁移到 Lightning Web 组件中的作用域模块导入。

AuraLightning Web 组件描述
$Browser@salesforce/client/formFactor返回有关运行浏览器的硬件的外形规格的信息。
$ContentAsset@salesforce/contentAssetUrl引用在 Lightning 组件中用作资产文件的图像、样式表和 JavaScript。
$Label@salesforce/label访问存储在代码外部的标签。
$Locale@salesforce/i18n返回有关当前用户的首选区域设置的信息。
$Resource@salesforce/resourceUrl引用您在静态资源中上传的图像、样式表和 JavaScript 代码。

迁移初始值设定项

将 Aura 组件中的事件处理程序替换为 Lightning Web 组件中的标准 JavaScript 方法。initconnectedCallback()

我们在 Aura 组件中使用该事件在组件构造之后但在渲染之前初始化组件。init

<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

组件控制器中的函数执行任何必要的初始化。doInit

({
  doInit: function (cmp) {
    // initialize component
  },
});

在 Lightning Web 组件中,改用组件的 JavaScript 文件。connectedCallback()

// mySampleInit.js
import { LightningElement } from "lwc";
export default class MySampleInit extends LightningElement {
  connectedCallback() {
    // initialize component
  }
}

迁移分面

将 Aura 组件中的分面迁移到 Lightning Web 组件中的插槽。

Aura 组件中的分面是类型为 的属性。例如:Aura.Component[]

<aura:component>
  <aura:attribute name="firstName" type="Aura.Component[]" />
  <aura:attribute name="lastName" type="Aura.Component[]" />

  <p>First Name: {!v.firstName}</p>
  <p>Last Name: {!v.lastName}</p>
</aura:component>

在 Lightning Web 组件中,我们使用插槽而不是分面。此模板定义了两个命名槽。

<!-- namedSlots.html -->
<template>
  <p>First Name: <slot name="firstName">Unknown</slot></p>
  <p>Last Name: <slot name="lastName">Unknown</slot></p>
</template>

此代码使用组件。<c-namedslots>

<!-- slotsWrapper.html -->
<template>
  <c-named-slots>
    <span slot="firstName">Willy</span>
    <span slot="lastName">Wonka</span>
  </c-named-slots>
</template>

此 HTML 是呈现的输出。

<p>First Name: <span>Willy</span></p>
<p>Last Name: <span>Wonka</span></p>

迁移基本组件

基本 Lightning 组件是 Salesforce 在命名空间中提供的构建块。当您在两种编程模型中使用基本 Lightning 组件时,它们具有不同的语法。lightning

迁移基本组件标记

此 Aura 组件使用基本组件。lightning:formattedText

<aura:component>
    <lightning:formattedText linkify="true" value="I like salesforce" />
</aura:component>

要将此标记迁移到 Lightning Web 组件:

  • 替换为 .<aura:component></aura:component><template></template>
  • 将分隔命名空间和组件名称的冒号更改为短划线。
  • 验证 Aura 基础 Lightning 组件是否可用作 Lightning Web 组件。请参阅组件库。
  • 将驼峰大小写组件名称 () 更改为以短划线分隔的名称 ()。formattedTextformatted-text
  • 删除布尔属性上的 or 值。如果存在,则布尔属性表示其值为 。truefalsetrue
  • 将自闭合标记更改为完整结束标记 ()。</lightning-formatted-text>

下面是等效的 Lightning Web 组件。

<template>
  <lightning-formatted-text linkify value="I like salesforce"></lightning-formatted-text>
</template>

迁移基本组件事件处理程序

Aura 基础组件上的大多数事件处理程序都具有等效的 Lightning Web 组件。此 Aura 组件使用带有事件处理程序的基本组件。lightning:buttononclick

<aura:component>
    <lightning:button
      label="Submit"
      title="Submit record data"
      onclick="{! c.handleClick }" />
</aura:component>

若要检索触发事件的按钮上的标签,请使用 .clickevent.getSource()

({
  handleClick: function (cmp, event, helper) {
    alert("You clicked: " + event.getSource().get("v.label"));
  },
});

下面是等效的 Lightning Web 组件。

<template>
  <lightning-button label="Submit" title="Submit record data" onclick={handleClick}>
  </lightning-button>
</template>

若要获取对调度事件的组件的引用,请使用该属性,该属性公开了基组件上的公共属性。例如,使用 、 返回单击组件上的标签event.targetlightning-buttonevent.target.label

import { LightningElement } from "lwc";
export default class MigrateButton extends LightningElement {
  clickedButtonLabel;

  handleClick(event) {
    this.clickedButtonLabel = event.target.label;
  }
}

如果基本 Aura 组件使用 HTML 元素包装,以便您可以侦听组件上的 HTML 事件,请将事件处理程序移动到基本 Lightning Web 组件。例如,支持多个事件处理程序,但不支持 .但是,Aura 使您能够创建包装器来处理事件。lightning:inputonkeydowndivkeydown

<div onkeydown="{!c.handleKeyDown}">
  <lightning:input type="search" value="{!v.value}" onchange="{!c.handleChange}" />
</div>

下面是等效的 Lightning Web 组件。

<lightning-input
  value={val}
  label="Enter some text"
  onchange={handleChange}
  onkeydown={handleKeyDown}
>
</lightning-input>

并非 Aura 基本组件中的所有事件处理程序都具有等效的 Lightning Web 组件。有关每个基本组件的规范,请参阅组件库。

迁移注意事项

一些基本的 Lightning Web 组件提供了比 Aura 对应组件更丰富的功能集。某些基本组件可能需要更多更改才能迁移。基本组件:Aura 与 Lightning Web 组件中记录了组件差异。

组件库包括基本组件的示例、文档和规范。在组件的参考页面中,要比较 Lightning Web 组件及其对应的 Aura 组件,请单击“以 Aura 组件形式查看”或“以 Lightning Web 组件形式查看”。

迁移已注册的事件

在 Lightning Web 组件中,Aura 组件标记中的标记没有等效项来注册组件可以触发事件。<aura:registerEvent>

迁移事件处理程序

在 Lightning Web 组件中,没有用于配置事件处理程序的 Aura 组件标记中的标记的等效项。<aura:handler>

迁移访问控制

将 Aura 组件的访问控制迁移到 Lightning Web 组件配置文件中的相应值。将 Aura 组件中属性的访问控制迁移到 JavaScript 属性装饰器和值的适当组合。<isExposed><isExposed>

要管理对 Aura 捆绑包资源(如组件或属性)的访问,请使用 system 属性。例如,此组件具有全局访问权限,这意味着该组件可以添加到托管包中并在另一个组织中使用。如果 Aura 组件实现了适当的接口,则还可以在其他组织的 Lightning 应用程序生成器或 Experience Builder 中使用。access

<aura:component access="global">
    ...
</aura:component>

Lightning Web 组件中的访问控制机制不同,其中访问由 JavaScript 属性装饰器和组件的配置文件定义。

元件

以下是 Aura 组件的访问值如何映射到 Lightning Web 组件。公共

仅在您的组织内可用。

在组件的配置文件中设置。<isExposed>false</isExposed>全球

在所有组织中都可用。该组件可以添加到托管包中,并在另一个组织中使用。Aura 组件还可以在其他组织的 Lightning 应用程序生成器或 Experience Builder 中使用。

在组件的配置文件中设置。<isExposed>true</isExposed>

属性

以下是 Aura 属性的访问值如何映射到 Lightning Web 组件。私人

仅在组件中可用。

使用 JavaScript 字段。公共

仅在您的组织内可用。

在 Lightning Web 组件中执行这两个步骤。

  1. 将 JavaScript 字段与装饰器一起使用。@api
  2. 在组件的配置文件中设置。<isExposed>false</isExposed>

全球

在所有组织中都可用。

在 Lightning Web 组件中执行这两个步骤。

  1. 将 JavaScript 属性与装饰器一起使用。@api
  2. 在组件的配置文件中设置。<isExposed>true</isExposed>

迁移事件

将 Aura 组件中的组件事件迁移到 Lightning Web 组件中的标准 DOM 事件。

以下是在 Lightning Web 组件中处理事件的概述。创建活动

而不是 Aura 组件中的专有对象,而是使用或标准 DOM 对象。在 Lightning Web 组件中,Aura 组件标记中的标记没有等效项来注册组件可以触发事件。EventEventCustomEvent<aura:registerEvent>触发事件

在 Lightning Web 组件中使用 ,而不是在 Aura 组件中使用 ,这是一种标准的 DOM 方法。event.fire()this.dispatchEvent(myEvent)处理事件

Aura 组件使用标记中的标记来定义处理程序。或者,当组件在其标记中引用另一个组件时,它可以声明处理程序操作。此 Aura 组件在其标记中使用,并为触发的 声明一个处理程序。<aura:handler>c:childhandleChildEventsampleComponentEventc:child

<c:child sampleComponentEvent="{!c.handleChildEvent}" />

Lightning Web 组件可以类似地声明声明性处理程序。声明性处理程序中的事件名称以 为前缀。on<!– prettier-ignore –>

<c-child onsampleComponentEvent={handleChildEvent}></c-child>

事件处理程序函数 在组件的 JavaScript 文件中定义。handleChildEvent

在 Lightning Web 组件中,您还可以使用组件的 JavaScript 文件中的标准方法以编程方式设置处理程序。addEventListener()检索事件负载

除非另有说明,否则使用该属性检索事件有效负载。event.detail

迁移应用程序事件

使用 Lightning 消息服务 (lightning/messageService) 与单个页面或多个页面中的组件进行通信。您还可以使用 pub-sub 模式在单个页面中的组件之间进行通信。

迁移标准Aura事件

此表将标准 Aura 事件(例如用于导航到组件或显示记录创建面板)映射到 Lightning Web 组件中的使用情况。未列出的事件目前在 Lightning Web 组件中没有等效事件。

Aura 组件Lightning Web 组件描述
aura:locationChange当窗口的哈希值更改时,将触发浏览器事件。若要处理此事件,请使用 onhashchange 事件处理程序。hashchange在浏览器位置栏中 URL 的哈希部分被修改时触发。
aura:valueChange将属性与自定义 getter 和 setter 方法结合使用。在属性值更改时触发。
aura:valueDestroy使用生命周期钩子。请参阅组件生命周期。disconnectedCallback()当组件被销毁时触发。
aura:valueInit若要替换事件处理程序,请使用生命周期挂钩。请参阅迁移初始值设定项。initconnectedCallback()在组件初始化时触发。
aura:valueRender使用 或 lifecycle 挂钩。请参阅组件生命周期。renderedCallback()render()在渲染组件时触发。
force:createRecord使用导航服务。显示记录创建面板。
force:editRecord使用导航服务。显示记录编辑面板。
force:navigateHome(已弃用)使用导航服务。导航到记录主页。
force:navigateToComponent(已弃用)使用导航服务。导航到组件。
force:navigateToList使用导航服务。导航到列表视图。
force:navigateToObjectHome使用导航服务。导航到对象主页。
force:navigateToRelatedList使用导航服务。导航到相关列表。
force:navigateToSObject使用导航服务。导航到记录。
force:navigateToURL使用导航服务。导航到 URL。
force:refreshView要刷新通过线路服务预配的 Apex 数据,请调用 refreshApex()。如果您的代码强制调用 Apex 方法,请通过再次调用该方法来刷新数据,然后调用 notifyRecordUpdateAvailable(recordIds) 以更新 Lightning 数据服务 (LDS) 缓存。仅当您希望在 LDS 缓存中更新任何相关数据时,才需要调用。向 LDS 发出某些记录已过时的信号,并刷新 LDS 缓存中的那些记录。notifyRecordUpdateAvailable()notifyRecordUpdateAvailable()在不重新加载页面的情况下重新加载视图。
force:showToast导入模块。请参阅 Toast 通知lightning/platformShowToastEvent显示 Toast 消息,以提醒用户成功、错误或警告。
lightning:openFiles使用导航服务。请参阅打开文件。打开一条或多条文件记录。
lightning:tabClosed计划在将来发布。在成功关闭控制台工作区或子选项卡时触发。
lightning:tabCreated计划在将来发布。在成功创建控制台工作区或子选项卡时触发。
lightning:tabFocused计划在将来发布。当控制台工作区或子选项卡处于焦点状态时触发。
lightning:tabRefreshed计划在将来发布。在成功刷新控制台工作区或子选项卡时触发。
lightning:tabReplaced计划在将来发布。在成功替换控制台主选项卡或子选项卡时触发。
lightning:tabUpdated计划在将来发布。在控制台工作区或子选项卡更新(包括标签、图标或其他内容更改)时触发。
ltng:afterScriptsLoaded从模块导入静态资源和导入方法。请参阅使用第三方 JavaScript 库。lightning/platformResourceLoader在加载了ltng:requireltng:require.scripts

注意

我们的前瞻性声明适用于计划在未来版本中的功能支持。由于路线图项目可能随时更改,因此请根据当前可用的技术做出购买决策。

迁移接口

通过实施 Aura 接口,您可以接收上下文数据或在不同的上下文中显示自定义组件,例如在 Lightning 应用程序生成器或体验生成器中。

要在 Lightning Web 组件中接收上下文数据,请导入相应的模块。若要在不同的上下文中显示组件,请使用配置文件中的元数据。targets*.js-meta.xml

未列出的 Aura 接口目前在 Lightning Web 组件中没有等效接口。

客户端:availableForMailAppPage

在:*.js-meta.xml

<targets>
  <target>lightning__Inbox</target>
</targets>

指示该组件可在 Lightning 应用程序构建器中用于添加到 Outlook 和 Gmail 集成的电子邮件应用程序窗格中。 请参阅为 Outlook 和 Gmail 集成创建组件。

客户端:hasEventContext

import { LightningElement, api } from 'lwc';
  @api dates;
  @api location;

在:*.js-meta.xml

<targets>
  <target>lightning__Inbox</target>
</targets>

指示组件在与 Outlook 和 Gmail 集成一起使用时获取有关事件的上下文信息。请参阅为 Outlook 和 Gmail 集成创建组件。

客户端:hasItemContext

import { LightningElement, api } from 'lwc';
  @api mode;
  @api people;
  @api source;
  @api subject;
  @api messageBody;

*.js-meta.xml:

<targets>
  <target>lightning__Inbox</target>
</targets>

指示组件在与 Outlook 和 Gmail 集成一起使用时获取有关电子邮件或日历事件的上下文信息。请参阅为 Outlook 和 Gmail 集成创建组件。

flexipage:availableForAllPageTypes

*.js-meta.xml:

<targets>
  <target>lightning__AppPage</target>
  <target>lightning__RecordPage</target>
  <target>lightning__HomePage</target>
  <target>lightning__UtilityBar</target>
</targets>

指示该组件可用于记录页、实用工具栏和任何其他类型的页。将每个页面类型显式指定为目标。请参阅为 Lightning 应用程序生成器配置组件和为实用程序栏配置组件。

flexipage:availableForRecord首页

<targets>
  <target>lightning__RecordPage</target>
</targets>

指示该组件仅适用于记录页。

force:hasRecordId

import { LightningElement, api } from 'lwc';
  @api recordId;

*.js-meta.xml:

<targets>
  <target>lightning__RecordPage</target>
</targets>

指示组件采用记录 ID 作为属性。请参阅使组件了解其记录上下文。

force:hasSObjectName

import { LightningElement, api } from 'lwc';
  @api objectApiName;

*.js-meta.xml:

<targets>
  <target>lightning__RecordPage</target>
</targets>

指示组件采用当前记录的对象类型的 API 名称。请参阅使组件了解其对象上下文。

力:闪电快速动作

*.js-meta.xml:

<targets>
  <target>lightning__RecordAction</target>
</targets>
<targetConfigs>
  <targetConfig targets="lightning__RecordAction">
    <actionType>ScreenAction</actionType>
  </targetConfig>
</targetConfigs>

指示组件是快速操作。请参阅配置组件以执行快速操作。

注意

LWC 快速操作目前仅在记录页面上受支持。

force:lightningQuickActionWithoutHeader

*.js-meta.xml:

<targets>
  <target>lightning__RecordAction</target>
</targets>
<targetConfigs>
  <targetConfig targets="lightning__RecordAction">
    <actionType>ScreenAction</actionType>
  </targetConfig>
</targetConfigs>

指示组件是没有标头的快速操作。请参阅配置组件以执行快速操作。

注意

LWC 快速操作目前仅在记录页面上受支持。

forceCommunity:availableForAllPageTypes

*.js-meta.xml:

<targets>
  <target>lightningCommunity__Page</target>
</targets>

指示该组件可在Experience Builder中使用。请参阅为 Experience Builder 配置组件。

lightning:hasPageReference

import { CurrentPageReference } from 'lightning/navigation';
  @wire(CurrentPageReference) pageRef;

指示组件接受 PageReference。请参阅导航到页面、记录和列表。

迁移 CSS

Lightning Web 组件使用标准的 CSS 语法。删除 Aura 组件使用的专有类。THIS

下面是 Aura 组件的 CSS 文件。

.THIS .red {
  background-color: red;
}

.THIS .blue {
  background-color: blue;
}

.THIS .green {
  background-color: green;
}

删除 THIS 关键字

迁移的 Lightning Web 组件的 CSS 文件是相同的,只是删除了 .THIS

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}

.green {
  background-color: green;
}

迁移基本 Lightning 组件的 CSS

目前,并非所有基本组件都支持迁移 CSS 文件。假设您正在迁移以下 Aura 标记。lightning:button

<lightning:button label="Reset" class="buttonColor buttonText"/>

使用以下 CSS 选择器。lightning:button

.THIS .buttonColor {
  background-color: red;
}

.THIS .buttonText {
  color: lightgray;
}

当您使用 Lightning Web 组件时,自定义类将应用于组件的外部元素,这意味着以下标记不会显示预期的样式。lightning-buttonlightning-buttonlightning-button

<!-- Custom styling does not work here -->
<lightning-button label="Reset" class="buttonColor buttonText"></lightning-button>

注意

您的自定义 CSS 会自动将范围限定为您自己的组件,以防止基本组件内部的样式化。我们建议您尽可能使用 Lightning Design System 类或基本 Lightning 组件上的变体。

在这种情况下,我们建议您使用 上的 variant 属性。例如,使用变体将背景颜色设置为红色。lightning-buttondestructive

<lightning-button label="Reset" variant="destructive"></lightning-button>

让我们看一下另一个示例,其中迁移 CSS 可以适用于基本组件。例如,您有以下标记。lightning:formattedAddress

<div class="mailingAddress">
  <lightning:formattedAddress
    street="1 Market St."
    city="San Francisco"
    country="US"
    province="CA"
    postalCode="94105"
  />
</div>

该组件使用以下 CSS 选择器。

.THIS .mailingAddress a {
  color: red;
}

使用该属性应用自定义样式。class

<!-- Custom styling works here -->
<lightning-formatted-address
  class="mailingAddress"
  street="121 Spear St."
  city="San Francisco"
  country="US"
  province="CA"
  postal-code="94105"
></lightning-formatted-address>
.mailingAddress {
  color: red;
}

迁移 JavaScript

将 JavaScript 代码从客户端控制器、帮助程序和渲染器移动到 Lightning Web 组件中的单个 JavaScript 文件。

Aura 组件中的客户端控制器是采用对象文字表示法的 JavaScript 对象,其中包含名称/值对的映射。Lightning Web 组件中的 JavaScript 文件是 ES6 模块,因此您使用的是标准 JavaScript,而不是 Aura 组件中使用的专有格式。

这不是逐行转换,而是重新审视组件设计的好机会。

要在 Lightning Web 组件和 Aura 组件之间共享 JavaScript 代码,请将代码放在 ES6 模块中。有关更多信息,请参阅在 LWC 和 Aura 之间共享 JavaScript 代码。

迁移 Apex

Aura 组件和 Lightning Web 组件都使用 Apex 控制器来读取或保存 Salesforce 数据。这两种编程模型没有语法差异。

Lightning Web 组件还可以使用 JavaScript 装饰器来包装对 Apex 方法或用户界面 API 的调用。@wire

数据绑定行为与 Aura 的差异

在标记中添加组件时,可以根据所有者组件的属性值初始化组件中的公共属性值。在 Lightning Web 组件中,属性值的数据绑定是单向的。Lightning Web 组件和 Aura 开发模型的数据绑定行为是不同的。

Aura

Aura 有两种形式的数据绑定表达式语法。

下面总结了表达式语法形式之间的差异。{#expression}(未绑定表达式)

数据更新的行为与您在 JavaScript 中的预期一样。基元(如 )按值传递,父项和子项中表达式的数据更新是分离的。String

对象(如 或 )通过引用传递,因此对子项中数据的更改将传播到父项。但是,父级中的更改处理程序不会收到通知。相同的行为也适用于传播到子项的父项中的更改。ArrayMap{!expression}(绑定表达式)

任一组件中的数据更新都通过两个组件中的双向数据绑定进行反映。同样,更改处理程序在父组件和子组件中都会触发。

Lightning Web 组件

属性值的组件之间的数据绑定是单向的。

若要从父组件向下通信到子组件,请在子组件上设置属性或调用方法。

若要从子组件向上通信到父组件,请发送事件。

有关更多信息,请参见设置子组件的属性。

基本组件:Aura 与 Lightning Web 组件

许多基本的 Lightning Web 组件具有与 Aura 对应组件相同的功能和属性。有些有细微的差异。

Lightning Web 组件继承了全局 HTML 属性和事件,使其比 Aura 组件更具功能性和性能。组件引用未列出每个组件的全局 HTML 属性和事件。参见 MDN 上的全局属性和事件。

对于组件样式,基本 Aura 组件和 Lightning Web 组件都支持设计变体和 SLDS 实用程序类。基本 Aura 组件还支持使用您自己的类进行自定义样式设置。但是,Lightning Web 组件遵循影子 DOM 标准,这阻止了使用您自己的类进行自定义样式。某些基本 LWC 组件支持用于自定义样式的 SLDS 样式挂钩。请参阅使用 Lightning Design System 样式挂钩设置组件样式。

下表列出了 Aura 基本组件与其 Lightning Web 组件对应组件之间的使用差异。Aura组件遵循名称格式,使用冒号分隔命名空间和组件名称。Lightning Web 组件遵循名称格式,用破折号分隔命名空间和组件名称。namespace:componentNamenamespace-component-name

表 1.Aura 组件到 Lightning Web 组件的映射

NamespaceAura 组件Lightning Web 组件差异
lightningaccordionaccordionlightning:accordion支持在简单标记中初始化多个打开的部分。要使用多个打开的部分进行初始化,请使用 JavaScript 传递部分名称数组。lightning-accordion
lightningaccordionSectionaccordion-sectionlightning:accordionSection通过传入组件的 actions 属性支持自定义菜单。当您将鼠标悬停在折叠式部分上时,Aura 组件的属性会提供工具提示文本。 支持通过插槽执行自定义菜单操作。Lightning Web 组件中的属性目前保留供内部使用。actionslightning:buttonMenutitlelightning-accordion-sectionactionslightning-button-menutitle
lightningavataravatar
lightningbadgebadge
lightningbreadcrumbbreadcrumb
lightningbreadcrumbsbreadcrumbs
lightningbuttonbutton
lightningbuttonGroupbutton-group
lightningbuttonIconbutton-iconlightning-button-icon不支持 .iconClass
lightningbuttonIconStatefulbutton-icon-stateful
lightningbuttonMenubutton-menulightning:buttonMenu不支持 AND 事件处理程序。onclickonclose
lightningbuttonStatefulbutton-stateful在 中,使用属性在选择按钮时显示。在 中,使用属性。lightning:buttonStatefulstatelightning-button-statefulselected
lightningcardcard在 中,可以将 和 属性设置为字符串或对象,这样就可以传递组件。您可以使用该属性指定要在卡片标题中显示的 或。在 中,可以将 和 属性设置为仅文本。若要包含标记或其他组件,请使用命名槽。您只能在命名槽中指定操作。lightning:cardtitlefooteractionslightning:buttonlightning:buttonIconlightning-cardtitlefooteraction
lightningcarouselcarousel
lightningcheckboxGroupcheckbox-group
lightningclickToDialclick-to-dial
lightningcomboboxcombobox
lightningcontainerLightning Web 组件尚不可用。
lightningdatatabledatatablelightning:datatable不支持表格单元格中的自定义数据类型。 仅支持自定义 CSS 类,用于设置标准数据类型列的样式。 支持表格单元格中的自定义数据类型。 支持自定义 CSS 类,仅用于设置自定义数据类型的列样式。lightning:datatablelightning-datatablelightning-datatable
lightningdualListboxdual-listbox
lightningdynamicIcondynamic-icon
lightningfileCardLightning Web 组件尚不可用。
lightningfileUploadfile-upload
lightningflexipageRegionInfo在 Aura 中,用于使包含组件知道它可以占用的宽度。在 Lightning Web 组件中,将公共属性用于此目的。请参阅使组件具有宽度感知能力。flexipageRegionInfoflexipageRegionWidth
lightningflowflow请参阅在自定义 LWC 中创建和启动流。
lightningformattedAddressformatted-address
lightningformattedDateTimeformatted-date-time在 中,使用 true 或 false 字符串或变量设置属性。在 中,只能使用变量设置属性。字符串始终被解释为 true。lightning:formattedDateTimehour12lightning-formatted-numberhour12
lightningformattedEmailformatted-email
lightningformattedLocationformatted-location
lightningformattedNameformatted-name
lightningformattedNumberformatted-number在 中,使用属性指定要显示的数字类型。在 中,将属性用于此目的。lightning:formattedNumberstylelightning-formatted-numberformat-style
lightningformattedPhoneformatted-phone
lightningformattedRichTextformatted-rich-text
lightningformattedTextformatted-text
lightningformattedTimeformatted-time
lightningformattedUrlformatted-url
lightninghelptexthelptext
lightningiconicon
lightninginputinput
lightninginputAddressinput-address
lightninginputFieldinput-fieldlightning:inputField不提供指示字段已修改但未保存的方法。 支持一个属性,以指示该字段已被用户修改,但未保存或提交。有关详细信息,请参阅差异。 支持该属性,但同时支持 和 。lightning-input-fielddirtyrecordEditFormlightning:inputFieldreadonlylightning-input-fieldreadonlyread-only
lightninginputLocationinput-location
lightninginputNameinput-name
lightninginputRichTextinput-rich-textlightning:inputRichText要求您使用子组件添加“插入图像”按钮。它不支持插入链接按钮或自定义按钮。 提供用于插入图像和链接的按钮。 支持使用组件和 (Beta) 添加自定义按钮。lightning:insertImageButtonlightning-input-rich-textlightning-input-rich-textlightning-rich-text-toolbar-button-grouplightning-rich-text-toolbar-button
lightninginsertImageButton支持插入图像按钮,因此您不需要 .lightning-input-rich-textlightning:insertImageButton
lightninglayoutlayoutlightning:layout允许组件之间的 HTML 标记、文本、表达式和其他组件。 不允许在组件之间使用表达式或其他组件。但是,您可以在组件之间放置 HTML 标记和文本。lightning:layoutItemlightning-layoutlightning-layout-itemlightning-layout-item
lightninglayoutItemlayout-item请参阅的差异。lightning-layout
lightninglistViewLightning Web 组件尚不可用。
lightningmapmap
lightningmenuItemmenu-item
lightningnavigationnavigation模块在 Aura 组件中,使用该组件访问导航服务。在 Lightning Web 组件中,在组件的 JavaScript 中导入模块。请参阅导航到页面、记录和列表。lightning:navigationlightning/navigation
lightningnotificationsLibraryplatformShowToastEvent模块在 Aura 组件中,添加组件以创建通知和 Toast。库提供 和 事件。在 Lightning Web 组件中,将模块导入组件的 JavaScript 中。该模块提供了一个名为 的事件。LWC 尚不支持通知。 支持与 Aura 相同的参数、模式和变体。请参阅 Toast 通知。notificationsLibraryshowToastshowNoticelightning/platformShowToastEventShowToastEventShowToastEventshowToast
lightningoutputFieldoutput-field查看差异。recordViewForm
lightningoverlayLibrary在 Aura 组件中,添加组件以创建模式对话框和弹出框。该库提供 、 和方法。overlayLibraryshowCustomModal()showCustomPopover()notifyClose()
lightningpathLightning Web 组件尚不可用。
lightningpicklistPathLightning Web 组件尚不可用。
lightningpillpilllightning:pill要求属性包含头像或图标。该属性在 上不可用。 可以接受头像和图标作为嵌套组件。mediavariantlightning:pilllightning-pill
lightningpillContainerpill-container
lightningprogressBarprogress-bar
lightningprogressIndicatorprogress-indicator
lightningprogressRingprogress-ring
lightningquipCardLightning Web 组件尚不可用。
lightningradioGroupradio-group
lightningrecordEditFormrecord-edit-formlightning:recordEditForm不需要直接将组件嵌套在其中。您可以将组件嵌套在 HTML 标记或其他组件中,例如定制布局。 旨在用作 的子项。您可以嵌套在 HTML 标记或其他基本组件中,例如 within 中。但是,不能嵌套在自定义组件中。lightning:inputFieldlightning:inputFieldlightning:layoutlightning-input-fieldlightning-record-edit-formlightning-input-fieldlightning-layoutlightning-record-edit-formlightning-input-field
lightningrecordFormrecord-form
lightningrecordViewFormrecord-view-formlightning:recordViewForm不需要您直接将组件嵌套在其中,尽管这是预期的用法。 必须是 的子项。不要嵌套在另一个元素中,例如 .您可以将其放置在容器中,例如 within 中。lightning:outputFieldlightning-output-fieldlightning-record-view-formlightning-output-fieldlightning-layoutlightning-record-view-form
lightningrelativeDateTimerelative-date-time
lightningselectLightning Web 组件尚不可用。在移动环境中,使用本机元素。在桌面环境中,请考虑使用 Lightning Web 组件。要支持多选,请使用 .<select>lightning-comboboxlightning-dual-listbox
lightningsliderslider
lightningspinnerspinner
lightningtabtab在 中,使用该属性分配一个字符串来标识选项卡。在 中,使用属性分配选项卡标识符。使用这些字符串来确定单击了哪个选项卡。lightning:tabidlightning-tabvaluetabset
lightningtabsettabsetlightning:tabset使用该属性指定打开的选项卡。 使用 .selectedTabIdlightning-tabsetactive-tab-value attribute
lightningtextareatextarea
lightningtiletile在 中,可用于添加包含头像组件或图标组件的属性。在 中,指定具有命名槽的头像和图标组件。lightning:tile<aura:set\>medialightning-tilemedia
lightningtreetree
lightningtreeGridtree-grid
lightningunsavedChangesLightning Web 组件尚不可用。
lightningverticalNavigationvertical-navigation
lightningverticalNavigationItemvertical-navigation-item
lightningverticalNavigationItemBadgevertical-navigation-item-badge
lightningverticalNavigationItemIconvertical-navigation-item-icon
lightningverticalNavigationItemOverflowvertical-navigation-item-overflow
lightningverticalNavigationSectionvertical-navigation-section
auraexpression自定义 JavaScript请参阅迁移表达式。
aurahtml不适用
auraiflwc:if / lwc:elseif / lwc:else请参阅迁移条件。
auraiterationfor:each请参阅迁移迭代。
aurarenderIflwc:if / lwc:elseif / lwc:else请参阅迁移条件。
auratemplate不适用
auratext不适用
auratoken不适用
auraunescapedHTML不适用
forcecanvasApp不适用
forceinputFieldinput-fieldforce:inputField已被 in Aura 取代。要根据字段类型创建可编辑字段,请使用 Lightning Web 组件或其对应的 Lightning Web 组件。lightning:inputFieldlightning:inputFieldlightning:recordEditForm
forceoutputFieldoutput-fieldforce:outputField已被 in Aura 取代。要根据字段类型创建只读字段,请使用 或其对应的 Lightning Web 组件。lightning:outputFieldlightning:outputFieldlightning:recordViewForm
forcerecordData@wire请参阅了解 Wire Service。
forcerecordEditrecord-edit-formforce:recordEdit已替换为 。lightning:recordEditForm
forcerecordViewrecord-view-formforce:recordView已替换为 。lightning:recordViewForm
ltngrequireplatformResourceLoader模块在 Aura 组件中,将标记添加到组件标记以引用外部静态资源。在 Lightning Web 组件中,将模块导入组件的 JavaScript 中。请参阅使用第三方 JavaScript 库。<ltng:require>lightning/platformResourceLoader

记录主页的 LWC 迁移

作为 Salesforce LWC 支持计划的一部分,标准对象的大多数记录主页都已转换为 LWC,包括详细信息、突出显示和相关列表。

将记录主页转换为使用 LWC 可加快页面加载和呈现速度,这在用于创建、编辑或查看记录的大型页面布局中尤其明显。

记录主页具有此 URL 模式。

https://my-domain-name.my.salesforce.com/lightning/r/ObjectApiName/RecordId/ViewOrEdit

例如,您可以像这样查看帐户的记录主页。

https://my-dev-org.my.salesforce.com/lightning/r/Account/xxxxxxxxxxxxxxxQAD/view

Lightning Web 组件和 Aura 组件协同工作

互操作性层使 Lightning Web 组件和 Aura 组件能够在应用程序中协同工作。

您可以编写新的 Lightning Web 组件,并将其添加到包含 Aura 组件的应用程序中。或者,您可以通过将应用程序中的单个 Aura 组件替换为 Lightning Web 组件来按计划迭代迁移。

Lightning Web 组件和 Aura 组件可以协同工作,但您必须了解一些限制。

重要

Aura 组件可以包含 Lightning Web 组件。但是,反之则不然。Lightning Web 组件不能包含 Aura 组件。

从 Lightning Web 组件编写 Aura 组件

您可以从 Lightning Web 组件组成 Aura 组件,但不能以相反的方式组合。为了在层次结构中向下通信,父级设置子级的属性。要决定何时以及如何将 Lightning Web 组件嵌套在 Aura 组件中,了解分面和插槽非常重要。

在 Aura 组件中,要引用 Aura 组件或 Lightning Web 组件,请使用驼峰大小写,并用冒号分隔命名空间和组件名称。

此 Aura 组件由 ,前者是基本的 Lightning 组件,后者是 Lightning Web 组件。lightning:cardc:lwcHelloWorld

<!-- auraComponent.cmp file -->
<aura:component implements="flexipage:availableForAllPageTypes">
  <lightning:card title="Aura Hello World" iconName="custom:custom30" />
  <c:lwcHelloWorld name="Earthling" />
</aura:component>

该代码显示经典问候语。(它还引用了组件。大多数基本 Lightning 组件都以 Aura 和 LWC 的形式提供。lwcHelloWorldlightning-card

<!-- lwcHelloWorld.html -->
<template>
  <lightning-card title="LWC Hello World" icon-name="custom:custom14">
    <div class="slds-card__body slds-card__body_inner">Hello, {name}!</div>
  </lightning-card>
</template>

该组件具有一个公共属性,Aura 组件使用该属性设置该属性。namename

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

export default class HelloWorld extends LightningElement {
  @api name;
}

提示

在 trailheadapps/pure-aloe 示例应用程序中,请参阅 Aura irrigationWrapperManager 组件,该组件设置子 irrigationManager Lightning Web 组件的属性。

刻面和插槽

在 Aura 组件和 Lightning Web 组件中,您可以将组件添加到另一个组件的主体中。在 Aura 中,将组件添加到分面中。在 Lightning Web 组件中,您可以将组件添加到插槽中。

在 Aura 中,属性是一个 facet。分面是任何类型的属性,这只是一种奇特的说法,你可以为属性设置一个组件数组。bodyAura.Component[]

用更不花哨的术语来说,把一个切面想象成一个三明治。您可以将任意数量的成分(组件)塞入三明治(切面)中。

<aura:component>
  <!-- start of component body facet-->
  <p>Feeling hungry?</p>
  <c:bacon />
  <c:lettuce />
  <c:tomato />
  <!-- end of component body facet -->
</aura:component>

构建 Aura 组件还是 Lightning Web 组件?

您可能渴望了解更多信息,甚至可能在阅读了有关 Aura 中的方面后享用午餐。现在,让我们看看您决定构建 Aura 组件还是 Lightning Web 组件的方面因素。

如果您正在构建一个新的 Lightning Web 组件,该组件需要其主体中的其他子组件,则这些子组件也必须是 Lightning Web 组件。请记住,Lightning Web 组件不能包含 Aura 组件。

想象一下,一个 Lightning Web 组件是嵌套组件树中最外层的组件。将闪电网络组件视为俄罗斯套娃中最大的娃娃,也称为俄罗斯套娃。俄罗斯套娃包含一组嵌套娃娃,每个娃娃包含一个较小的娃娃。如果最大的玩偶是 Lightning Web 组件,那么较小的嵌套玩偶都不能是 Aura 组件。

示例:将组件传递到插槽中

考虑一个允许在其主体中使用其他组件的 Lightning Web 组件。标记是所有者组件可以将标记传递到其中的占位符。c-wrapper<slot>

<!-- wrapper.html -->
<template>
  <slot></slot>
</template>

Lightning Web 组件将组件传递到插槽中。c-applightning-card

<!-- app.html -->
<template>
  <c-wrapper>
    <lightning-card>
      <lightning-icon icon-name="utility:connected_apps"></lightning-icon>
      Card Title
      <p class="slds-p-horizontal_small">Card Body</p>
    </lightning-card>
  </c-wrapper>
</template>

重要

如果 Lightning Web 组件包含插槽,您可以将其嵌套在 Aura 组件中,但不能使用该插槽。

从父 Aura 组件调用子 Lightning Web 组件方法

要从 Aura 组件调用 Lightning Web 组件中定义的方法,请为 Lightning Web 组件提供 并使用 ,就像引用 Aura 组件一样。例如。aura:idcmp.find()cmp.find('childLwc').childLwcMethod()

在 Aura 组件渲染之前,不会创建 Lightning Web 组件。在此之前(例如,在 Aura 组件初始化期间),您无法在 Lightning Web 组件上调用方法。

将事件发送到封闭的 Aura 组件

若要从子级与父级进行通信,请调度事件。Lightning Web 组件触发 DOM 事件。封闭的 Aura 组件可以侦听这些事件,就像封闭的 Lightning Web 组件一样。封闭的 Aura 组件可以捕获事件并处理它。(可选)Aura 组件可以触发 Aura 事件,以便与其他 Aura 组件或应用容器进行通信。

提示

lwc-recipes 存储库中的 auraEmbeddedLWC 组件展示了如何在父 Aura 组件中嵌入 Lightning Web 组件并与事件进行通信。

下面的示例演示了此技术。此 Lightning Web 组件在其 JavaScript 文件中触发自定义事件。filterchange

// categoryFilter.js
import { LightningElement } from "lwc";

export default class CategoryFilter extends LightningElement {
  handleCheckboxChange() {
    // Get the labels of selected checkboxes
    const filters = Array.from(this.template.querySelectorAll("lightning-input"))
      .filter((element) => element.checked)
      .map((element) => element.label);
    const filterChangeEvent = new CustomEvent("filterchange", {
      detail: { filters },
    });
    // Fire the custom event
    this.dispatchEvent(filterChangeEvent);
  }
}
<!-- categoryFilter.html -->
<template>
  <lightning-input
    label="Category 1"
    type="checkbox"
    onchange={handleCheckboxChange}
  ></lightning-input>
  <lightning-input
    label="Category 2"
    type="checkbox"
    onchange={handleCheckboxChange}
  ></lightning-input>
</template>

封闭的 Aura 组件包装器为自定义事件添加处理程序。请注意,事件处理程序 与前缀为“on”的事件名称匹配。也就是说,用于处理名为 的事件。onfilterchangeonfilterchangefilterchange

<!-- auraDomEventListener.cmp -->
<aura:component implements="flexipage:availableForAllPageTypes">
    <aura:attribute name="message" type="String" default="No selection"/>

    <lightning:card title="AuraDomEventListener" iconName="custom:custom30">
        <aura:set attribute="actions">
            <span class="aura">Aura Component</span>
        </aura:set>
        <div class="slds-m-around_medium">
            <lightning:layout>
                <lightning:layoutItem size="4">
                    <!-- This is an LWC component -->
                    <c:categoryFilter onfilterchange="{!c.handleFilterChange}"/>
                </lightning:layoutItem>
                <lightning:layoutItem size="8" class="slds-p-left_medium">
                    {!v.message}
                </lightning:layoutItem>
            </lightning:layout>
        </div>
    </lightning:card>
</aura:component>

注意

您只能在 DOM 事件冒泡到的第一个 Aura 组件中指定一个处理程序。onfilterchange

Aura 组件的控制器接收事件。您可以随心所欲地处理该事件。此组件对在 Lightning Web 组件事件的属性中传递的数组进行操作。您可以选择触发新的 Aura 事件以与其他 Aura 组件进行通信。filtersdetails

// auraDomEventListenerController.js
({
  handleFilterChange: function (component, event) {
    var filters = event.getParam("filters");
    component.set(
      "v.message",
      filters.length > 0 ? "Your selection: " + filters.join() : "No selection",
    );
  },
});

在 LWC 和 Aura 之间共享 JavaScript 代码

要在 Lightning Web 组件和 Aura 组件之间共享 JavaScript 代码,请将代码放在服务组件的 ES6 模块中。

要共享 ES6 模块:

  1. 使用 Lightning Web 组件编程模型创建服务组件(库)。
  2. 要在 Lightning Web 组件中使用代码,请在组件的 JavaScript 文件中导入并引用它。
  3. 若要在 Aura 组件中使用代码,请使用导入 Aura 组件并调用其方法时所用的相同语法。有关示例代码,请参阅 Aura lightning:navigationItemAPI 组件文档。请注意,这是一个 Aura 组件,而不是 ES6 模块,但要导入 ES6 模块,请使用相同的 Aura 语法。lightning:navigationItemAPI

提示

lwc-recipes 存储库有一个模块,用于实现 Lightning Web 组件和 Aura 组件之间的通信。该模块已停用,但可以在不支持 Lightning 消息服务的 Experience Cloud 等容器中使用。lmsPublisherWebComponentpubsub

将 Salesforce 外部的组件与 Lightning Out(测试版)配合使用

使用 Lightning Out 在 Salesforce 服务器之外运行组件。无论是在 Heroku 上运行的 Node.js 应用程序,还是防火墙内的部门服务器,都可以将您的 Lightning Web 组件添加到独立的 Aura 依赖项应用程序中。然后,无论用户身在何处,都可以运行它们。

注意

此版本包含 Lightning Out 的测试版,这意味着它是一项具有已知限制的高质量功能。您可以在 IdeaExchange 上提供对 Lightning Out 的反馈和建议。

开发可部署在任何地方的 Lightning Web 组件通常与开发它们在 Salesforce 中运行相同。您所知道的有关组件开发的所有内容仍然适用。区别在于如何将应用嵌入远程 Web 容器或源服务器。

以 JavaScript 库的形式将 Lightning Out 添加到外部应用程序,这些库包含在源服务器上的页面中。添加标记以配置和激活您的独立 Aura 应用程序。初始化后,Lightning Out 会通过安全连接拉入 Lightning 组件应用程序,将其启动,然后将其插入到运行它的页面的 DOM 中。到达此点后,您的 Lightning Web 组件代码将接管并运行节目。

注意

此方法不同于使用 iframe 嵌入应用。通过 Lightning Out 运行的 Lightning Web 组件是页面上的正式公民。如果您愿意,您可以启用独立 Aura 应用程序与您嵌入的页面或应用程序之间的交互。此交互使用 Lightning 事件进行处理。

除了一些简单的标记外,Salesforce 中还有少量的设置和准备工作,以实现 Salesforce 和源服务器之间的安全连接。而且,由于源服务器托管应用程序,因此您需要使用自己的代码管理身份验证。

此设置过程类似于您对使用 Lightning Platform REST API 连接到 Salesforce 的应用程序执行的操作,您应该期望它需要同等的工作量。

闪电输出要求

使用 Lightning Out 部署 Lightning Web 组件需要满足一些要求,以确保连接性和安全性。

远程 Web 容器

验证远程 Web 容器或源服务器是否支持这些要求。

  • 能够修改提供给客户端浏览器的标记,包括 HTML 和 JavaScript。您必须能够添加 Lightning Out 标记。
  • 能够获取有效的 Salesforce 会话 ID。
  • 能够访问您的 Salesforce 实例。例如,如果源服务器位于防火墙后面,则它需要访问Internet的权限,至少可以访问Salesforce。

闪电储物柜

使用 Lightning Locker,这是 Lightning 组件的安全体系结构。启用 Lightning Web Security 时,不支持 Lightning Out。我们建议将 Lightning Web Security 作为大多数组织的首选安全架构,但如果您使用 Lightning Out,则必须改用 Lightning Locker。

Salesforce组织

配置您的 Salesforce 组织。

  • 创建连接的应用程序,以便源服务器可以进行身份验证和连接。
  • 将源站加入跨域资源共享(CORS)白名单。

Lightning 依赖应用程序

创建一个特殊的独立 Aura 应用程序,其中包含源服务器上托管的所有 Lightning Web 组件的依赖关系信息。此应用程序仅供 Lightning Out 使用。

浏览器第三方 Cookie

要使用 Lightning Out,您必须设置自定义域,或者您的 Safari 用户必须更改其跨站点跟踪浏览器设置。此要求适用于桌面和移动设备上的 Safari 用户。有关更多详细信息,请参阅为闪电输出启用浏览器第三方 Cookie。

启用浏览器第三方 Cookie 以实现闪电输出

Lightning 组件在用户的浏览器中设置 Cookie。由于 Lightning Out 在 Salesforce 外部运行 Lightning 组件,因此这些 Cookie 是“第三方”Cookie。有几种替代方法可以使这些第三方 Cookie 在 Lightning Out 中发挥作用。

启用基于令牌的身份验证

Salesforce 使用 Cookie 进行身份验证。对于 Lightning Out 应用程序,我们建议您启用在 Lightning 应用程序处于第三方上下文中时将身份验证 Cookie 替换为会话令牌的设置。

在“设置”的“快速查找”框中,输入“会话”,然后选择“会话设置”。在“会话设置”页面上,选择“在第三方站点中嵌入 Lightning 应用程序时,请使用会话令牌而不是会话 Cookie”。

如果未启用此设置,则用户必须在其浏览器设置中允许第三方 Cookie。

在 Safari 中启用跨站点跟踪

Salesforce 使用身份验证 Cookie 以外的 Cookie。要使这些来自 Salesforce 的第三方 Cookie 正常工作,您的用户必须在其浏览器设置中允许第三方 Cookie。

默认情况下,“阻止跨站点跟踪”设置在 iOS 和 iPadOS 13.4 以及 Safari 浏览器 13.1 及更高版本中处于启用状态。若要允许第三方 Cookie 并使用 Lightning Out,必须禁用此设置。

要查看“阻止跨网站跟踪”设置,请执行以下操作:

  • 在 Mac 桌面上的 Safari 浏览器 App 中,前往 Safari |首选项,然后单击隐私。
  • 在 iOS 和 iPadOS 中,前往“设置”|”苹果浏览器

设置自定义域

要求所有 Safari 用户更改其跨站点跟踪浏览器设置的替代方法是设置自定义域。自定义域与调用“闪电输出”应用的外部服务器的第一级域匹配。这种方法会导致浏览器将外部服务器和 Lightning Out 应用程序视为同一域的一部分,因此可以在两个站点之间共享 Cookie。

例如,要从服务器调用 Lightning Out 应用程序,请在 Salesforce 中添加自定义域,例如 。您必须设置 DNS 记录以将完全限定域名 (FQDN) 映射到 Salesforce 中的自定义域 URL。external.example.comlightningout.example.comlightningout.example.com

  1. 确定自定义域名,例如 .自定义域必须解析为与调用 Lightning Out 应用程序的第三方站点相同的父域。lightningout.example.com
  2. 通过输入“快速查找”框,从“设置”中查找 18 个字符的组织 ID,然后选择“域”。单击“添加域”,并记下页面顶部列出的组织 ID。Domains
  3. 使用 DNS 提供商设置 CNAME 记录,以将自定义域名(例如 )映射到 Salesforce 中的自定义域。CNAME 记录的目标使用格式 ,其中 是您在第一步中选择的自定义域名。lightningout.example.comYourFQDN.Your18charOrgId.live.siteforce.comYourFQDN
  4. 通过完成“添加域”页创建自定义域。
    1. 对于 Domain Name (域名),输入您在第一步中选择的自定义域名,例如 。lightningout.example.com
    2. 对于 HTTPS 选项,选择 Salesforce 使用您的 HTTPS 证书在 Salesforce 的服务器上通过 HTTPS 提供域。
  5. 在外部服务器页面上配置闪电输出标记,以使用 CNAME 记录的 FQDN,例如 ,这是您使用 DNS 提供商设置的。标记中的属性和函数中的参数都必须使用 CNAME 记录的 FQDN。lightningout.example.comsrcscriptlightningEndPointURI$Lightning.use()
  6. 如果您的应用使用身份验证,请参阅闪电输出身份验证。

闪电输出依赖项

创建一个特殊的独立 Aura 依赖项应用程序来描述要使用 Lightning Out 部署的组件。

一个独立的 Aura 依赖项应用只是一个具有一些属性的依赖项,以及使用标签描述的依赖组件。独立的 Aura 依赖项应用程序并不是您真正部署为供人们直接使用的应用程序的应用程序。独立的 Aura 依赖项应用仅用于指定 Lightning Out 的依赖项。<aura:application><aura:dependency>

此独立的 Aura 依赖项应用程序使用默认命名空间中的 Lightning Web 组件。myAppComponentc

<aura:application access="GLOBAL" extends="ltng:outApp">
    <aura:dependency resource="c:myAppComponent"/>
</aura:application>

注意

要在 Aura 应用程序或 Aura 组件中引用 Lightning Web 组件,请使用命名约定。<namespace:camelCaseComponentName>

使用独立的 Aura 依赖应用程序

独立的 Aura 依赖项应用必须执行以下操作。

  • 将访问控制设置为 。GLOBAL
  • 从 或 扩展。ltng:outAppltng:outAppUnstyled
  • 将调用 中引用的每个组件作为依赖项列出。$Lightning.createComponent()

在此示例中,是您计划使用 在源服务器上创建的顶级 Lightning Web 组件。使用 为添加到页面的每个组件创建一个依赖项。<c:myAppComponent>$Lightning.createComponent()$Lightning.createComponent()

注意

不要担心顶级组件中使用的组件。该框架处理子组件的依赖项解析。

独立的 Aura 依赖应用程序不是普通的 Aura 应用程序,您不应将其视为一个应用程序。仅用于指定 Lightning Out 应用的依赖项。

特别要注意以下几点。

  • 无法将模板添加到独立的 Aura 依赖项应用。
  • 添加到独立 Aura 依赖项应用正文的内容不会呈现。

定义样式依赖关系

您有两种选项可用于设置 Lightning Out 应用程序的样式:Salesforce Lightning Design System 和 unstyled。Lightning Design System 样式是默认样式,Lightning Out 会自动将当前版本的 Lightning Design System 包含在使用 Lightning Out 的页面上。要省略 Lightning Design System 资源并完全控制您的样式,也许是为了匹配源服务器的样式,请将您的依赖项应用程序设置为 extend from 而不是 .ltng:outAppUnstyledltng:outApp

闪电输出标记

Lightning Out 需要在页面上添加一些简单的标记,并使用两个简单的 JavaScript 函数激活。

Lightning Out 库中的标记和 JavaScript 函数是 Lightning Out 唯一特有的功能。其他一切都是您已经知道和喜爱的 Lightning Web 组件代码。

将 Lightning Out 库添加到页面

通过将 Lightning Out JavaScript 库包含在托管独立 Aura 依赖项应用程序的应用程序或页面中,启用源服务器以与 Lightning Out 一起使用。包含库需要一行标记。

<script src="https://myDomainName.my.salesforce.com/lightning/lightning.out.js"></script>

重要

使用主机的自定义域。不要从示例源代码中复制和粘贴其他人的实例。如果这样做,则每当 Salesforce 实例与从中加载 Lightning Out 库的实例之间存在版本不匹配时,您的应用程序就会中断。在Salesforce的定期升级期间,这种情况每年至少发生三次。别这样!

加载和初始化 Lightning 组件应用程序

使用该函数加载并初始化 Lightning 组件框架和独立的 Aura 依赖项应用程序。$Lightning.use()

该函数有四个参数。$Lightning.use()

名字类型描述
appName字符串必填。独立 Aura 依赖项应用的名称,包括命名空间。例如。"c:expenseAppDependencies"
callback功能在 Lightning 组件框架和应用程序完全加载后调用的函数。回调不接收任何参数。此回调通常是你调用将应用添加到页面的位置(请参阅下一节)。还可以通过其他方式更新显示内容,或者以其他方式响应依赖项应用准备就绪。$Lightning.createComponent()
lightningEndPointURI字符串Salesforce 实例上 Lightning 域的 URL。例如。https://myDomainName.lightning.force.com
authToken字符串有效、活动 Salesforce 会话的会话 ID 或 OAuth 访问令牌。您必须在自己的代码中获取此令牌。Lightning Out 不会为您处理身份验证。请参阅闪电输出的身份验证。

appName是必需的。其他三个参数是可选的。通常,您需要提供所有四个参数。

注意

您不能在一个页面上使用多个独立的 Aura 依赖项应用。可以多次调用,但必须在每次调用中引用相同的依赖项应用。$Lightning.use()

将 Lightning Web 组件添加到页面

使用该功能在页面上添加并激活您的组件。$Lightning.createComponent()

该函数有四个参数。$Lightning.createComponent()

名字类型描述
componentName字符串必填。要添加到页面的 Lightning Web 组件的名称,包括命名空间。例如。"c:newExpenseForm"
attributes对象必填。创建组件时要在组件上设置的属性。例如。如果组件不需要任何属性,请传入一个空对象 .{ name: theName, amount: theAmount }{ }
domLocator元素或字符串必填。指示在页面上插入所创建组件的位置的 DOM 元素或元素 ID。
callback功能在组件添加到页面并在页面上处于活动状态后调用的函数。回调接收创建的组件作为其唯一参数。

注意

您可以向一个页面添加多个 Lightning Web 组件。也就是说,您可以使用多个 DOM 定位器多次调用,以将组件添加到页面的不同部分。以这种方式创建的每个组件都必须在页面的独立 Aura 依赖项应用中指定。$Lightning.createComponent()

在幕后,调用 Aura 中的标准函数。除了 DOM 定位器之外,参数是相同的。除了将调用包装在一些 Lightning Out 语义中之外,行为也是相同的。$Lightning.createComponent()$A.createComponent()

来自 Lightning Out 的身份验证

要处理身份验证,您必须在初始化 Lightning Out 应用程序时手动提供 Salesforce 会话 ID 或身份验证令牌。

有两种受支持的方式来获取用于闪电输出的身份验证令牌。

  • 在 Visualforce 页面上,您可以使用表达式 获取当前 Visualforce 会话 ID。使用会话 ID 启动的会话只能在 Visualforce 页面上使用。{! $Api.Session_ID }
  • 在其他地方,使用 OAuth 获取经过身份验证的会话,其过程与获取用于 REST API 的经过身份验证的会话的过程相同。在这种情况下,您将获得 OAuth 令牌,并且可以在任何地方使用它。

重要

Lightning Out 不会自动为您处理身份验证。该函数只是将您提供的任何身份验证令牌传递给安全子系统。对于大多数组织,令牌是会话 ID 或 OAuth 令牌。$Lightning.use()

Lightning Out 具有与您从中获取身份验证令牌的会话相同的权限。对于 Visualforce 使用,会话具有当前用户的权限。对于 OAuth,它是定义 OAuth 连接应用时使用的任何 OAuth 范围设置。通常,将 Lightning Out 与 OAuth 结合使用需要向返回 OAuth 令牌的连接应用程序授予“完全访问权限”范围。{! $Api.Session_ID }

当使用会话访问令牌授予经过 Lightning Out 身份验证的会话时,该会话将保留对活动浏览器会话中运行的任何域的访问。用户使用有效的访问令牌登录后,将在活动浏览器会话中运行的所有 Salesforce 应用程序中验证会话凭据。lightning.force.com

为了防止会话持久性,Salesforce 管理员可以将会话锁定到原始 IP 地址。要选择此选项,请导航到:

设置>安全>会话设置

激活“将会话锁定到会话源自的 IP 地址”复选框。

与未经身份验证的用户共享 Lightning Out 应用程序

将界面添加到您的独立 Aura 依赖项应用程序,使其可供用户使用,而无需他们向 Salesforce 进行身份验证。通过此界面,您可以使用 Lightning Web 组件构建应用程序,并将其部署到任何地方和任何人。ltng:allowGuestAccess

注意

如果用户已通过 Lightning Out 端点进行身份验证,则必须在 中设置会话。尽管我们谈论的是未经身份验证的用户,但如果用户已通过身份验证,了解要求也很重要。$Lightning.use()

用法

您可以将带有界面的独立 Aura 依赖项应用程序添加到 Visualforce 页面,也可以将其与托管在 Salesforce 外部的 Lightning Out 应用程序一起使用。ltng:allowGuestAccess

  • 使用适用于 Visualforce 的 Lightning Web 组件,您可以将依赖项应用程序添加到 Visualforce 页面,然后在 Salesforce 选项卡 + Visualforce 站点中使用该页面。然后,您可以允许公众访问该页面。
  • 使用 Lightning Out,您可以在支持 Lightning Out 的任何地方部署依赖项应用程序,这几乎是任何地方!

该界面仅在启用了数字体验的组织中可用,并且您的 Lightning Out 应用程序与您在组织中定义的所有站点终结点相关联。ltng:allowGuestAccess

重要

当您通过添加界面使依赖项应用程序可供访客用户访问时,无论该站点是否启用了公共访问,都可以通过组织中的每个 Experience Cloud 站点访问该应用程序。您无法阻止通过站点 URL 访问它,也无法使其可用于某些网站,而不适用于其他网站。ltng:allowGuestAccess

注意

对于为访客访问打开的应用,请格外小心。启用访客访问的应用程序会绕过您为站点的访客用户配置文件设置的对象级和字段级安全性 (FLS)。当您引用或检索对象时,组件不会在 Apex 方法中自动强制执行 CRUD 和 FLS。该框架继续显示用户没有 CRUD 访问权限和 FLS 可见性的记录和字段。启用来宾访问的应用中使用的代码错误可能会向全世界开放组织的数据。

示例:允许访客访问 Lightning Out 应用程序

将界面添加到独立的 Aura 依赖项应用。ltng:allowGuestAccess

<aura:application access="GLOBAL" extends="ltng:outApp"
    implements="ltng:allowGuestAccess">

    <aura:dependency resource="c:storeLocatorMain"/>

</aura:application>

注意

只能将接口添加到依赖项应用,而不能添加到单个组件。ltng:allowGuestAccess

接下来,将 Lightning Out JavaScript 库添加到您的页面。

  • 使用适用于 Visualforce 的 Lightning Web 组件,只需在页面上的任意位置添加标签即可。<apex:includeLightning />
  • 借助 Lightning Out,使用站点终结点 URL 添加直接引用库的标记。<script><script src="https://YOURSITEDOMAIN/SITEURL/lightning/lightning.out.js"></script>例如:https://universalcontainers.force.com/ourstores/lightning/lightning.out.js

最后,添加 JavaScript 代码以加载和激活依赖项应用。此代码是标准的 Lightning Out,但重要的补充是,您必须将组织的站点 URL 之一用于端点。终结点 URL 采用 的格式,如本示例所示。https://YOURSITEDOMAIN/SITEURLhttps://universalcontainers.force.com/ourstores/

<script>
  $Lightning.use(
    "c:locatorApp", // name of the Lightning app
    function () {
      // Callback once framework and app loaded
      $Lightning.createComponent(
        "c:storeLocatorMain", // top-level component of your app
        {}, // attributes to set on the component when created
        "lightningLocator", // the DOM location to insert the component
        function (cmp) {
          // callback when component is created and active on the page
        },
      );
    },
    "https://universalcontainers.force.com/ourstores/", // Site endpoint
  );
</script>

闪电输出注意事项和限制

使用 Lightning Out 创建应用程序通常与使用 Lightning Web 组件创建任何应用程序一样。但是,由于您的组件在 Salesforce 外部运行,因此您需要注意一些问题。

您必须注意的问题可以分为两类。

使用闪电输出的注意事项

由于 Lightning Out 应用程序在任何 Salesforce 容器之外运行,因此您需要牢记并可能解决一些事项。浏览器支持

Lightning Out 支持与 Lightning Experience 相同的浏览器。这种支持意味着您的 Lightning Out 应用程序和组件会在这些浏览器中加载。但是,如果组件或功能不支持特定浏览器,则该组件或功能在 Lightning Out 中也无法运行。性能

Lightning Out 无法从 Lightning Experience 的许多缓存功能中受益,因此启动和性能通常较慢。浏览器第三方 Cookie

Lightning 组件在用户的浏览器中设置 Cookie。由于 Lightning Out 在 Salesforce 之外运行 Lightning 组件,因此这些 Cookie 是“第三方”Cookie。要使 Lightning Out 应用程序能够与第三方 Cookie 配合使用,请参阅闪电输出要求。认证

没有 Salesforce 容器可以为您处理身份验证,因此您必须自己处理。Authentication from Lightning Out 中详细讨论了这一重要主题。

标准组件的局限性

虽然 Lightning Out 的核心功能稳定且完整,但我们仍在努力与其他 Salesforce 功能进行一些交互。

这些功能中最主要的是内置于 Lightning 组件框架中的标准组件。许多标准组件在独立环境中使用时无法正常运行,例如 Lightning Out 和基于 Lightning Out 的 Lightning Web Components for Visualforce。此限制是因为组件依赖于容器中的可用资源。one.app

若要避免自己的组件出现此问题,请明确其依赖项。用于引用未嵌入组件本身的所有必需静态资源。@salesforce/resourceUrl

如果您在应用程序中使用标准组件,则在 Lightning Out 或 Lightning Web Components for Visualforce 中使用它们时,它们可能没有完全样式或行为与文档中所述。

“组件库”中的“组件引用”为每个组件都有一个“体验”字段,其中列出了组件支持的容器。