快速入门:探索Visualforce至LWC示例应用程序 – 将Visualforce部署到LWC示例应用程序

学习目标

在此项目中,您将:

  • 将Visualforce部署到LWC示例应用程序。
  • 探索从Visualforce到LWC的示例应用程序及其示例代码。
  • 了解如何将五个关键模式实现为Lightning Web组件。

欢迎使用Visualforce开发人员!我们很高兴你在这里。我们凭借在Visualforce中的开发经验,特别为您编写了该项目。

Visualforce转LWC示例应用程序

为什么我们创建Visualforce到LWC示例应用程序?Visualforce是一种流行且被广泛采用的技术。许多开发人员维护Visualforce页面,甚至在一些新项目上,开发人员仍然选择使用Visualforce。我们知道从Visualforce过渡到Lightning Web Components可能会令人生畏。

我们创建了Visualforce至LWC示例应用程序,以帮助您进行Lightning Web Components编程。该应用程序与等效的Lightning Web组件一起显示Visualforce中的常用模式。我们为这两种实现提供了代码,因此您可以比较它们并了解Lightning Web组件代码与您熟悉的Visualforce代码有何不同。您甚至可以在学习时自行复制,粘贴,改编和试验代码。

您熟悉的一些Visualforce概念也适用于Lightning Web组件。有些没有。适用于Visualforce开发人员的 Lightning Web组件 模块将Visualforce概念映射到Lightning Web组件。它还强调并说明了开发Lightning Web组件与使用Visualforce开发在根本上不同的方式。在探索从Visualforce到LWC的示例应用程序之前或之后,应对Visualforce Developers的Lightning Web Components模块。它们是互补的。

Visualforce至LWC应用程序显示四种布局模式:页面块,面板网格,面板栏和选项卡。 每个示例都有一个Visualforce实现和一个LWC实现。

关于这个项目

在此快速入门项目中,您将从Trailhead样本库安装样本应用程序 。该示例应用程序包含一些示例,您可以使用这些示例来了解Lightning Web组件。它还具有代码,可让您从头开始开发自己的Lightning Web组件。

如果您想浏览示例应用程序库,请参阅 快速入门:浏览示例应用程序库。

在你开始之前

在执行此动手项目中的步骤之前,请确保完成“ 快速入门:闪电Web组件”。该徽章将引导您完成在Salesforce DX开发环境中的设置和工作。

注意

要创建和开发Lightning Web组件,您需要一套称为Salesforce DX(开发人员体验)的工具。它包括Salesforce命令行界面(CLI)和Visual Studio代码,该代码与Salesforce Extension Pack一起,是在Salesforce平台上开发的推荐代码编辑器。

要克隆包含示例应用程序的存储库,请使用版本控制系统Git。请按照此步骤中的说明安装Git。然后按照示例应用程序自述文件中的说明克隆示例应用程序存储库,并将示例应用程序部署到您的Trailhead Playground。

创建一个新的Trailhead游乐场

对于此项目,您需要创建一个新的Trailhead Playground。滚动到该页面的底部,单击“启动”旁边的向下箭头,然后选择“ 创建Trailhead游乐场”。创建新的Trailhead游乐场通常需要3-4分钟。

注意:是的,我们的意思是全新的Trailhead游乐场!如果您使用现有的组织或游乐场,则可能会遇到无法完成挑战的问题。

获取您的Trailhead Playground用户名和密码

让我们开始吧。转到您的Trailhead游乐场。(如果尚未打开,请滚动至该页面的底部,然后单击启动。)如果您在组织中看到一个标签为Get Your Login Credentials的标签,太好了!跳至步骤1。

否则,请从应用启动器(应用启动器)中找到并打开Playground Starter,然后按照以下步骤操作。如果您没有看到Playground Starter应用程序,请 在Trailhead帮助中签出 查找Trailhead Playground的用户名和密码。

  1. 单击获取您的登录凭据选项卡,并记下您的用户名。
  2. 单击重置我的密码。这会将电子邮件发送到与您的用户名关联的地址。
  3. 单击电子邮件中的链接。
  4. 输入新密码,确认,然后单击 更改密码

获取Git命令行

  1. 从https://git-scm.com/downloads安装Git 。接受所有默认安装设置。
  2. 确认已安装Git。在终端(macOS)或命令提示符(Windows)中,输入以下命令:
    git
    输出应为git命令列表。

部署应用

现在,您已经安装并集成了所有工具,现在可以使用Visual Studio Code将Visualforce部署到Trailhead Playground中的LWC示例应用程序。

  1. 打开Visual Studio代码。
  2. 打开命令面板:单击 查看| 命令面板
    或者,按Ctrl + Shift + P(Windows)或Cmd + Shift + P(macOS)
  3. 打开终端窗口:单击 终端| 新航站楼
    在此处输入或粘贴以下说明中提供的命令。
  4. 按照项目自述文件中的说明将应用程序部署到您的Trailhead Playground组织中 ,跳过步骤3。(您无需为标准Trailhead Playground注册“我的域”。)

适用于Visualforce开发人员的Lightning Web组件 – 使用导航服务并重新使用Visualforce

学习目标 

完成本单元后,您将能够:

  • 说明如何在Lightning Web组件中实现导航模式。
  • 评估是将特定的Visualforce功能移至Lightning还是将其保留在Visualforce中。
  • 描述Lightning Web组件如何与Visualforce页面交互。

我们已经看到了如何使用一些Visualforce概念来理解Lightning Web Components基础。我们还看到了如何有效使用Salesforce数据。在本单元中,我们涵盖两个剩余的概念:导航和Visualforce重用。最后,我们用一些建议的后续步骤包装了此模块。

URLFOR与导航服务

执行导航任务的模式在Visualforce中很常见。Visualforce页面通常使用URLFOR带有<apex:commandButton><apex:commandLink>标记的功能来导航到Salesforce内部或外部的页面。Apex控制器方法还可以通过返回来简化导航PageReferences。 

以编程方式从Lightning Web组件导航到其他任何地方的首选方法是使用 Lightning Navigation Service。该服务允许您生成URL,导航到页面引用,使用URL参数以及打开文件。支持许多 页面引用类型,例如App,Lightning Component,Navigation Item(选项卡)和Record Page。

导航服务通过使用有意义的PageReference对象来执行导航,从而消除了硬编码的URL 。如果Salesforce更改了特定的URL,则链接到该URL的代码不会中断。

要使用导航服务:

  1. lightning/navigationJavaScript模块导入Lightning Web组件。
  2. 使Lightning Web组件的类扩展NavigationMixin
  3. 调用该Navigate方法,传递要导航到的页面的页面引用。

注意

混入是一种特殊类型的JavaScript类的。其他类可以在不继承mixin类的情况下调用mixin中的方法。

考虑此示例,该示例使用导航服务导航到联系人列表页面。

clientSideNavigation.js

import { LightningElement } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
export default class ClientSideNavigation extends NavigationMixin(LightningElement) {
    handleButtonClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: 'Contact',
                actionName: 'list'
            }
        });
    }
}

代码重点:

  • 第2行:我们NavigationMixinlightning/navigation模块导入。
  • 第3行:ClientSideNavigation定义组件的类扩展了NavigationMixin
  • 第4-10行:当handleButtonClick方法运行时(在用户单击按钮之后),导航服务将用户重定向到listContact对象的页面。这可以通过调用mixinNavigate方法来实现。

在Lightning体验中重用Visualforce

假设您想继续在Lightning Experience中使用Visualforce页面。你可以做到的。许多低代码工具都支持Visualforce页面,包括Lightning页面,Utility栏和Quick Actions。该 Visualforce和闪电体验模块解释了如何配置你的Visualforce页面在闪电体验使用。Visualforce和Lightning Web组件也可以共存于同一页面上并进行交互。

如果要在Visualforce页面上的特定位置包含Lightning Web组件,请使用 Visualforce JavaScript库的Lightning组件。该技术使用iframe,并为您提供了在组件和Visualforce页面之间进行通信的工具。

Visualforce的Lightning组件适用于Aura组件和Lightning Web组件。

使用Lightning Message Service可以促进DOM的不同层次结构中的Lightning组件和Visualforce页面之间的通信。LWC Recipes示例应用程序演示了如何使用Lightning Message Service发布和订阅消息。

重建与重用

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

  • 更具吸引力和响应能力的用户体验。
  • 易于针对多种设备尺寸进行优化的体验。
  • 在您的应用程序中获得更好的性能。

对于新开发,我们始终建议使用Lightning Experience低代码工具和Lightning Web组件。它们提供了各种好处并简化了开发过程。

包起来

恭喜你!除了学习Lightning Web组件的体系结构和编码概念,访问数据以及处理服务器错误之外,您还创建并部署了四个Lightning Web组件。 

现在您已经了解了Visualforce与Lightning Web Components的比较方式,我们希望从Visualforce过渡到Lightning Web Components的开发似乎没有那么艰巨。通过Trailhead上的这些学习资源,继续您的Lightning Experience UI开发之旅。

适用于Visualforce开发人员的Lightning Web组件 – 使用Salesforce数据

学习目标

完成本单元后,您将能够:

  • 意识到根据特定用例选择最佳方式使用Salesforce数据的重要性。
  • 描述闪电数据服务如何与Visualforce中的标准控制器进行比较。
  • 说明在Lightning Web组件中使用Apex与在Visualforce中使用Apex有何不同。

Visualforce与Lightning Web组件中的数据访问

作为Visualforce开发人员,您熟悉在页面中使用标准控制器和绑定Apex控制器方法以使用Salesforce数据的情况。在Lightning Web Components中,您的JavaScript代码与Lightning Data Service(LDS)或Apex代码进行交互。

传统的Visualforce数据访问 闪电Web组件数据访问
客户端如何在Visualforce中访问服务器上的数据 客户端如何在Lightning Web Components中访问服务器上的数据

检索或修改数据的Visualforce页面使用标准控制器或Apex控制器。传统上,客户端在页面加载或作为操作时调用控制器方法。方法运行后,Visualforce引擎将生成最终标记并将其发送给客户端。

检索或修改数据的Lightning Web组件使用Lightning Data Service或Apex方法。客户端使用JavaScript调用Lightning Data Service或Apex方法。在运行Lightning Data Service或Apex方法之后,Lightning Web Components引擎会将所需的最少数据返回给客户端。客户端上的JavaScript处理数据并生成最终标记。

闪电数据服务与StandardController

Lightning Data Service 是在Lightning Web组件中使用Salesforce数据的首选(也是最简单)方式。闪电数据服务是与Visualforce标准控制器类似的概念。在JavaScript中使用Lightning Data Service在不编写Apex代码的情况下读取,创建或修改单个记录,或读取某些元数据。Lightning Data Service提供了高级功能,例如组件之间的缓存和同步。

注意

要使用Lightning Data Service,您有两个选择:使用允许您构建表单的基本组件,或使用LDS电线适配器或功能。使用Lightning Data Service的代码非常具体,并且在Lightning Web组件和Salesforce数据 模块中的“使用Lightning Data Service来处理数据”中进行了详细说明 。

Visualforce中的Apex与Lightning Web Components中的Apex

Lightning Data Service不能满足所有用例的要求。例如,当您要自定义单记录数据事务或对单个事务执行多记录操作时,需要Apex。在将Apex与Lightning Web组件一起使用之前,请注意在Lightning Web组件中使用Apex与在Visualforce中使用Apex是不同的。主要区别在于:

  • 方法是无状态的。
  • 方法必须是@AuraEnabled,并且可以标记为可缓存。
  • 您导入Apex方法,然后调用它们。
  • 您绑定组件以在元数据xml文件中记录页面,并在JavaScript文件中访问记录ID。
  • 正确的错误处理涉及引发异常,而不是使用页面消息。

让我们进一步探讨这些差异。

查看状态与无状态方法

Visualforce使用视图状态来维护服务器请求之间的状态。视图状态将重新创建页面,并将状态传递到向导和指导工作流程中的不同页面。在Lightning Web组件中,服务器请求是无状态的。这对您编写Apex调用的方式具有重要意义。每次进行Apex调用时,都必须传递该方法所需的所有信息,并且该方法必须返回组件所需的所有信息。此外,要从Lightning Web组件调用Apex方法,该方法必须带有注释@AuraEnabled

让我们研究一下Visualforce Apex控制器。

AccountListControllerVisualforce.cls

public with sharing class AccountListControllerVisualforce {
    public List<Account> accounts { get; private set; }
    public Integer numberOfEmployees { get; set; }
    public void queryAccounts() {
        // In real world, probably more complex logic here
        this.accounts = [
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees = :numberOfEmployees
        ];
    }
}

代码重点:

  • 第2至3行:accounts和 numberOfEmployees属性定义为实例变量,它们是控制器视图状态的一部分。
  • 第6至9行:该queryAccounts方法numberOfEmployees在 accounts变量中存储了由过滤的帐户列表,我们可以在Visualforce页面中引用该列表。

以下是将该AccountListController for Visualforce转换为Lightning Web组件的控制器的方法。

  1. 使用@AuraEnabled,使用cacheable属性或不使用属性注释Apex方法。(默认情况下,数据 不可在客户端中缓存。)
  2. 通过使其成为无状态static且独立于所有实例变量和属性的方法,确保它们是无状态的。
  3. 将方法需要的所有内容作为参数传递。
  4. 确保每种方法都返回组件所需的一切。

这是适用于Lightning Web组件的控制器。

AccountListControllerLwc.cls

public with sharing class AccountListControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Account> queryAccounts(Integer numberOfEmployees) {
        return [ // Return whatever the component needs
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees >= :numberOfEmployees
        ];
    }
}

代码重点:

  • 第2行:使用注释queryAccounts方法 @AuraEnabled,并将其cacheable属性设置为true。
  • 第3行:创建queryAccounts方法static,并将其定义numberOfEmployees为Integer参数。
  • 第4-8行:该queryAccounts方法返回过滤后的帐户列表。

注意

将方法标记为可缓存时,避免重复调用服务器。但是,在刷新缓存之前,可能不会返回新添加或更改的记录版本。要了解缓存Apex方法的含义以及如何刷新缓存,请参阅Lightning Web Components和Salesforce数据 模块中的“使用Apex处理数据” 。

在Visualforce vs Lightning Web组件中调用Apex

在Visualforce中,要在组件标记中引用Apex方法,可以通过将Apex控制器指定为<apex:page>标签中的属性来将其绑定到Visualforce页面。在Lightning Web Components中,我们没有绑定控制器并引用页面中的Apex方法,而是将这些方法导入JavaScript文件,然后在JavaScript中调用这些方法。

import queryAccounts from '@salesforce/apex/AccountListControllerLwc.queryAccounts;

与Lightning Web组件中的Apex方法进行交互的方式有两种:连接方法或强制调用方法。接线方法将控件委派给Lightning Web Components引擎并创建响应服务。强制调用Apex会导致一次性调用。确切地说,何时以及如何使用每个选项超出了本模块的范围。要了解更多信息,请参阅 Lightning Web Components和Salesforce数据 模块。

在Visualforce vs Lightning Web组件中访问记录ID

在Visualforce中,访问Apex控制器中的记录ID非常简单。使用标准控制器,您可以IdApexPages.StandardController对象中检索记录 。

例如,考虑使用此Apex控制器,该控制器通过扩展使用“客户”标准控制器的页面来显示与客户相关的联系人。

AccountControllerVisualforce.cls

public with sharing class AccountControllerVisualforce {
    public List<Contact> contacts { get; private set; }
    private ApexPages.StandardController standardController;
    public AccountController(ApexPages.StandardController standardController) {
        this.standardController = standardController;
        this.contacts = new List<Contact>();
    }
    public void queryRelatedContacts() {
        this.contacts = [
            SELECT Name, Title, Email, Phone
            FROM Contact
            WHERE AccountId = :standardController.getId() // (2)
        ];
   }
}

代码重点:

  • 第4行:standardController因为页面使用Account标准控制器,所以我们在构造函数中收到一个对象。
  • 第12行:要获取Id页面引用的Account记录,我们getIdstandardController对象上调用方法 。这样,我们可以查询联系人以获取相关的客户记录,并为其过滤Id

在Lightning Web组件中,访问Apex中的记录ID不太简单。要访问记录ID:

  1. 公开组件,使其在记录页面上可用。
  2. 在JavaScript中,声明recordId为公共属性。父组件(记录Flexipage)填充recordId属性的值 。
  3. recordId在Apex方法调用中将as作为参数传递。

让我们来看一个例子。

accountDetails.js-meta.xml

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>

accountDetails.js

import { LightningElement, wire } from 'lwc';
import queryRelatedContacts from '@salesforce/apex/AccountControllerLwc.queryRelatedContacts';
export default class AccountInfo extends LightningElement {
    @api recordId;
    @wire(queryRelatedContacts, { accountId: '$recordId' })
    contacts;
}

AccountControllerLwc.cls

public with sharing class AccountControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Contact> queryRelatedContacts(Id accountId) {
        return [
            SELECT Name, Title, Email, Phone
            FROM Contact
            WHERE AccountId = :accountId
        ];
    }
}

代码重点:

accountDetails.js-meta.xml

  • 第4-7行:我们将其设置isExposed为true并添加 lightning__RecordPage为该组件的目标,以使该组件在记录页面上可用。

accountDetails.js

  • 第4行:我们声明该recordId属性,并使用修饰它以使其公开@api。Flexipage会填充 recordId属性。
  • 第5-6行:我们将recordId属性作为参数传递给 queryRelatedContactsApex方法的 accountId参数。(在这种情况下,我们使用了 @wire,但是我们可以强制性地调用Apex。)结果存储在contacts属性中。

AccountControllerLwc.cls

  • 第3行:queryRelatedContactsApex方法接收 accountId作为参数。请记住,该方法是无状态的。
  • 第4-8行:该queryRelatedContacts方法用于 accountId返回客户的联系人。

Visualforce与Lightning Web组件中的服务器错误

在Visualforce中,您使用诸如<apex:pageMessages>和之类的 标记 <apex:pageMessage>以在Visualforce页面上以不同方式显示错误。为了使这些标记正常工作,必须在Apex控制器中处理异常并将消息添加 到页面,如下所示:

try {
    // Perform logic that may throw an exception.
} catch (Exception e) {
    ApexPages.addMessages(e);
}

在Lightning Web组件中,我们处理JavaScript文件中的异常。作为开发人员,您可以决定是引发AuraHandledException 异常还是通过引发异常或自定义异常来让异常传播或更好地控制向用户显示的内容 。引发这样的自定义异常:

try {
    // Perform logic that may throw an exception.
} catch (Exception e) {
    throw new MyCustomException('Records could not be retrieved at this time. Try again later');
}

Lightning Web组件和Salesforce数据 模块 中更详细地介绍了处理服务器错误 。

调用Apex以检索过滤的记录

在您创建的accountSearch组件中,让我们检索按提供的员工数量过滤的帐户列表。

    1. 创建一个AccountListControllerLwc Apex类:
      1. 在Visual Studio Code命令面板中,选择(或输入) SFDX:Create Apex Class,然后按 Enter
      2. 输入文件名,AccountListControllerLwc然后按Enter
      3. 接受默认位置(类),然后按 Enter
    2. 用以下代码替换AccountListControllerLwc类的内容:
public with sharing class AccountListControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Account> queryAccountsByEmployeeNumber(Integer numberOfEmployees) {
        return [
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees >= :numberOfEmployees
        ];
   }
}
    1. 保存AccountListControllerLwc类。
    2. 在您的accountSearch.js文件中,通过使用以下代码替换第一行代码,导入wire装饰器和queryAccountsByEmployeeNumberApex方法:
import { LightningElement, wire } from 'lwc';
import queryAccountsByEmployeeNumber from '@salesforce/apex/AccountListControllerLwc.queryAccountsByEmployeeNumber';
  1. 最后,在reset方法之后,添加以下代码:
    @wire(queryAccountsByEmployeeNumber, { numberOfEmployees: '$numberOfEmployees' })
    accounts;
  2. 保存accountSearch.js文件。
  3. 在accountSearch.html文件中的之后<lightning-button>,添加以下代码:
    <template if:true={accounts.data}>
        <template for:each={accounts.data} for:item="account">
             <p key={account.Id}>{account.Name}</p>
        </template>
    </template> 
  4. 保存accountSearch.html文件。
  5. 将AccountListControllerLwc类文件部署到您的Trailhead游乐场:右键单击classes文件夹,然后选择 SFDX:将源部署到Org
  6. 将accountSearch组件文件部署到Trailhead Playground:右键单击accountSearch文件夹,然后选择 SFDX:将源部署到Org
  7. 如果您的Trailhead Playground尚未打开,请打开它。(在命令选项板中,选择(或输入)SFDX:Open Default Org。)
  8. 导航到LWC Visualforce Devs页面并通过在“员工人数”字段中输入值来测试您的组件。当您更改员工人数时,应更新帐户列表。

您只是从Lightning Web组件中的Salesforce组织访问数据。做得好!现在,通过完成动手练习来自己尝试一个。

适用于Visualforce开发人员的Lightning Web组件 – 处理JavaScript中的用户操作

学习目标

完成本单元后,您将能够:

  • 创建一个SFDX项目。
  • 创建一个闪电Web组件。
  • 应用架构和编码概念。

在Visualforce中,要执行UI更改,有时您需要在服务器上重新呈现页面。如您所知,在Lightning Web Components架构中,重新渲染发生在客户端上。您学习了如何在JavaScript中设置属性以更改组件状态,从而使Lightning Web Components引擎重新呈现组件。您还学习了如何响应JavaScript中的用户交互。让我们观察一下这些概念。考虑此示例Visualforce页面。

accountSearch.page

<apex:page controller="InputController" docType="html-5.0">
    <apex:form>
        <apex:input type="number" label="Number of Employees" value="{!numberOfEmployees}"/>
        <apex:commandButton value="Reset" action="{!reset}"/>
    </apex:form>
</apex:page>

AccountSearchController.cls

public class AccountSearchController {
    public Integer numberOfEmployees {get; set;}
    public void reset() {
        this.numberOfEmployees = null;
    }
}

重置按钮清除输入值,然后页面在服务器上重新呈现。在Lightning Web组件中,您可以单独使用JavaScript进行相同的UI更改,如下所示:

accountSearch.html

<template>
    <lightning-card>
        <lightning-input
            type="number"
            label="Number of Employees"
            value={numberOfEmployees}
            onchange={handleChange}>
        </lightning-input>
        <lightning-button
            label="Reset"
            onclick={reset}>
        </lightning-button>
    </lightning-card>
</template>

accountSearch.js

import { LightningElement } from 'lwc';
export default class AccountSearch extends LightningElement {
    numberOfEmployees = null;
    handleChange(event) {
        this.numberOfEmployees = event.detail.value;
    }
    reset() {
        this.numberOfEmployees = null;
    }
}

代码重点:

accountSearch.html

  • 第3-8行:我们使用一个lightning-input组件来接收用户输入。
  • 第6行:我们将numberOfEmployeesJavaScript属性绑定到lightning-input组件的value属性。
  • 第7行:我们将handleChange方法绑定到lightning-input组件的change事件。
  • 第9至12行:我们定义了lightning-button 基本组件
  • 第11行:当用户单击按钮时,Lightning Web Components引擎将调用该reset方法。

accountSearch.js 

  • 第5行:该handleChange方法读取lightning-input组件的change事件,获取用户输入的值,并将其存储在numberOfEmployees属性中。
  • 第7–9行:reset方法清空numberOfEmployees属性。通常,我们使用handleEventName约定来命名事件处理程序,但是在reset这里我们用来强调它与Apex控制器reset方法的相似性。

将传递valuelightning-input会导致组件重新呈现。与Visualforce实现的区别在于,重新渲染发生在客户端上,从而避免了对服务器的额外调用。

回应用户互动

现在,我们已经探索了Lightning Web Components和您熟悉的Visualforce开发之间的一些区别,让我们来看一个示例。

在你开始之前

Visualforce开发人员非常喜欢在开发人员控制台中工作。但是,Lightning Web Components的编程模型需要另一套称为Salesforce DX(开发人员体验)的开发人员工具。它包括Salesforce命令行界面(CLI)和Visual Studio代码,该代码与Salesforce Extension Pack一起,是在Salesforce平台上开发的推荐代码编辑器。Salesforce DX环境旨在:

  • 简化整个开发生命周期
  • 促进自动化测试
  • 支持持续集成
  • 使发布周期更加敏捷和高效

在开始本模块的动手练习和动手挑战之前,请确保您已完成《 快速入门:闪电Web组件》。该徽章的前两个步骤将逐步设置Salesforce DX开发环境。

创建一个新的Trailhead游乐场

对于此项目,您需要创建一个新的Trailhead Playground。滚动到该页面的底部,单击“启动”旁边的向下箭头,然后选择“创建Trailhead游乐场”。创建新的Trailhead游乐场通常需要3-4分钟。

注意:是的,我们的意思是全新的Trailhead游乐场!如果您使用现有的组织或游乐场,则可能会遇到无法完成挑战的问题。

获取您的Trailhead Playground用户名和密码

转到您的Trailhead游乐场。(如果尚未打开,请滚动至该页面的底部,然后单击启动。)如果您在组织中看到一个标签为Get Your Login Credentials的标签,太好了!跳至步骤1。 

否则,请从应用启动器(应用启动器)中找到并打开Playground Starter,然后按照以下步骤操作。如果您没有看到Playground Starter应用程序,请在Trailhead帮助中签出 查找Trailhead Playground的用户名和密码

  1. 单击获取您的登录凭据选项卡,并记下您的用户名。
  2. 单击重置我的密码。这会将电子邮件发送到与您的用户名关联的地址。
  3. 单击电子邮件中的链接。
  4. 输入新密码,确认,然后单击更改密码

准备好动手了吗?我们走吧。

在本练习中,您将创建一个Lightning Web组件,以响应用户交互而重新渲染。

    1. 创建一个新项目:
      1. 打开Visual Studio代码。
      2. 打开命令面板:单击查看命令面板
      3. 在命令面板中,选择SFDX:创建项目。(如果您没有在列表中看到它,请键入SFDX: Create Project,然后按Enter。)
      4. 接受标准模板。
      5. 输入项目名称,lwcForVisualforceDevs然后按Enter。
      6. 选择新项目的位置,然后单击“创建项目”
    2. 授权您的Trailhead游乐场:
      1. 在命令选项板中,选择(或输入)SFDX:授权组织
      2. 选择生产:login.salesforce.com
      3. 对于别名,请输入lwc_for_vf_devs,然后按Enter
      4. 使用您的Trailhead Playground用户名和密码登录。
      5. 登录到Trailhead Playground后,将其保持打开状态并返回到Visual Studio Code。
    3. 在Visual Studio Code中,打开一个终端窗口:单击Terminal |。新航站楼
    4. 在终端中,将Trailhead Playground设置为该项目的默认设置:输入此命令,然后按Enter
sfdx config:set defaultusername=lwc_for_vf_devs
    1. 创建一个闪电Web组件:
      1. 在“资源管理器”窗格中,展开“  force-app / main / default”。
      2. 右键单击lwc文件夹,然后选择SFDX:Create Lightning Web Component
      3. 输入组件名称,accountSearch然后按Enter键
      4. 再次按Enter接受默认目录。
    2. 用以下代码替换accountSearch.html文件的内容:
<template>
  <lightning-card>
      <lightning-input
          type="number"
          label="Number of Employees"
          value={numberOfEmployees}
          onchange={handleChange}>
      </lightning-input>
      <lightning-button
          label="Reset"
          onclick={reset}>
      </lightning-button>
  </lightning-card>
</template>
    1. 用以下代码替换accountSearch.js文件的内容:
import { LightningElement } from 'lwc';
export default class AccountSearch extends LightningElement {
    numberOfEmployees = null;
    handleChange(event) {
        this.numberOfEmployees = event.detail.value;
    }
    reset() {
        this.numberOfEmployees = null;
    }
}
    1. 要使此组件在组织中的应用程序页面上可用,请使用以下代码替换accountCreator.js-meta.xml文件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
    </targets>
</LightningComponentBundle>
  1. 保存您编辑的三个文件:accountSearch.html,accountSearch.js和accountSearch.js-meta.xml。
  2. 将项目文件部署到Trailhead Playground:右键单击lwc文件夹,然后选择SFDX:将源部署到Org
  3. 如果您的Trailhead Playground尚未打开,请打开它。(在命令选项板中,选择(或输入)SFDX:Open Default Org。)
  4. 在您的Trailhead游乐场中,点击 设定,然后点击设置
  5. 在“快速查找”框中,输入Lightning App Builder,然后选择Lightning App Builder
  6. 创建一个新的闪电页面:
    1. 点击新建
    2. 选择应用程序页面,然后单击下一步
    3. 对于标签,输入LWC Visualforce Devs,然后单击下一步
    4. 对于布局,选择Header和Left Sidebar
    5. 点击完成
  7. accountSearch组件拖动到页面侧栏。
  8. 保存页面。
  9. 激活页面:
    1. 点击激活
    2. 保留默认的应用程序名称(LWC Visualforce Devs),然后单击保存
    3. 当提示您将页面添加到导航菜单时,点击完成
  10. 退出Lightning App Builder。
  11. 打开新页面:在App Launcher搜索中,输入lwc,然后在Items下选择LWC Visualforce Devs
  12. 在输入字段中输入一个值,然后单击“重置”按钮。
    您实现的JavaScript代码应清除输入字段,并使Lightning Web Components引擎重新呈现该组件。

看那个!您创建了一个Lightning Web组件并将其添加到组织中的页面。现在尝试动手挑战中的另一只手。

适用于Visualforce开发人员的Lightning Web组件 – 了解编码概念如何应用于Lightning Web Components

学习目标 

完成本单元后,您将能够:

  • 解释Visualforce和Lightning Web组件之间的体系结构差异。
  • 将Visualforce编码概念映射到Lightning Web Components。

在本单元中,您将学习Visualforce知识如何应用于Lightning Web Components体系结构和编码概念。

闪电Web组件架构

Visualforce是服务器端的模板语言。当客户端(浏览器)请求Visualforce页面时,服务器将呈现该页面,并将其以HTML格式发送给客户端。当用户界面需要更改时(例如,响应链接单击页面),客户端将向服务器请求一个新呈现的页面。服务器处理UI更改并将整个页面发送回客户端。

在Lightning Web组件中,客户端承担了大部分繁重的工作。要渲染Lightning Web组件,它将向服务器请求组件文件,处理这些文件以生成适当的标记,然后渲染组件UI。因为客户端可以处理逻辑,所以有时它可以执行UI更改,而无需完全回调服务器。它仅在需要时(例如,组件需要新数据时)才调用服务器。即使这样,客户端仍需要最少数量的数据。

传统的Visualforce请求 闪电Web组件请求
传统的Visualforce请求图 Lightning Web组件请求图
  1. 用户请求页面。
  2. 服务器执行页面的基础代码,并将结果HTML发送到浏览器。
  3. 浏览器显示页面。
  4. 当用户再次与页面交互时,该循环从第一步开始重复。
  1. 用户请求组件。
  2. 组件定义作为已编译的JavaScript文件返回到客户端。
  3. JavaScript应用程序生成UI。
  4. 当用户再次与页面交互时,JavaScript会修改客户端上的UI。

JavaScript在Lightning Web组件中起着重要作用。每个组件都有一个JavaScript文件,可在需要时重新生成UI。组件还可以在需要时使用JavaScript调用服务器以检索或修改Salesforce数据。我们将在本模块的后面部分介绍数据访问。

闪电Web组件编码概念

Visualforce和Lightning Web组件有很大的不同,但是有一些Visualforce概念有助于理解JavaScript和HTML在Lightning Web组件中的交互方式。

使用属性跟踪状态

在Visualforce中,属性在Apex控制器(Apex类文件)中定义,并在页面标记(Visualforce页面)中引用。在Lightning Web组件中,属性在组件的JavaScript文件中定义,并在页面标记(组件的HTML文件)中引用。属性跟踪Visualforce页面和Lightning Web组件的状态。这是语法的基本示例。

hello.html

<template>
    {greeting}
</template>

hello.js

import { LightningElement } from 'lwc';
export default class Hello extends LightningElement {
    greeting = 'Hello World';
}

greeting可以从JavaScript读取值,但也可以例如响应用户操作来写入。当标记中引用的属性的值更改时,Lightning Web Components引擎将重新渲染该组件。用户操作和所导致的重新呈现完全发生在客户端上。不需要服务器请求。

使用Getter和Setter跟踪状态

您在Visualforce中知道的getter和setter也存在于Lightning Web组件中。您可以在JavaScript文件中定义它们。读取属性时,getter将执行逻辑。设置器在写入属性时执行逻辑。这是扩展属性功能的便捷方法。 

要定义吸气剂,请创建一个包含逻辑并在其前面加上get关键字的方法。要定义设置器,请使用进行相同的操作set。定义设置器是可选的。

在此示例中,我们itemName使用getter和setter定义属性。每次itemName设置属性时,设置器都会将值转换为大写。uppercaseItemName更改值时,Lightning Web Components引擎将为计算新值itemName,然后重新呈现该组件。

todoItem.html

<template>
    {itemName}
</template>

todoItem.js

import { LightningElement } from 'lwc';
export default class TodoItem extends LightningElement {
    uppercaseItemName;
    get itemName() {
        return this.uppercaseItemName;
    }
    set itemName(value) {
        this.uppercaseItemName = value.toUpperCase();
    }
}

注意: Lightning Web组件的标记不支持计算值的表达式。而是考虑使用getter来计算JavaScript文件中的值。 

有条件的渲染

在Visualforce中,您可以使用该rendered属性有条件地呈现标记。要在Lightning Web组件中有条件地呈现标记,请使用if:true|false template指令HTML模板指令是特殊属性,可为模板添加动态行为。其他知名的前端框架(例如Angular和Vue)也使用模板指令。

在此示例中,该areDetailsVisible属性在控制器(未显示)中定义。我们使用areDetailsVisible属性的值来控制页面上某个部分的可见性,如下所示:

helloConditionalRendering.html

<template>
    <template if:true={areDetailsVisible}>
        These are the details!
    </template>
</template>

包含“这些就是细节!”的模板 仅在areDetailsVisible属性值为时显示true

渲染清单

在Visualforce中,您可以使用<apex:repeat>标签来遍历列表。在Lightning Web组件中,两个模板指令执行迭代: for:eachiterator:iteratorName。在此示例中,我们遍历contacts 控制器中的 属性。

compositionIteration.html

<template>
    <template for:each={contacts} for:item="contact">
        <p key={contact.Id}>
            {contact.Name}
        </p>
    </template>
</template>

代码重点:

  • 第2行:我们使用for:eachtemplate指令一次遍历所有联系人。然后,我们使用for:itemtemplate指令创建contact变量,该变量在每次迭代中一次包含一个单独的联系人。
  • 第3行:的所有直接子代for:item必须包含唯一的key模板指令。

调用JavaScript

在Visualforce页面中,当用户与页面交互时,页面可以执行JavaScript。例如,页面可能包含<apex:commandButton>,以响应按钮click事件执行JavaScript逻辑。您可以通过将JavaScript逻辑绑定到onclick按钮的属性来实现。在Lightning Web组件中调用JavaScript的方式相同。但是,必须在JavaScript文件的方法中定义逻辑,并且该方法必须绑定到事件,如下所示:

eventHandler.html

<template>
    <a onclick={handleButtonClick}></a>
</template>

eventHandler.js

import { LightningElement } from 'lwc';
export default class EventHandler extends LightningElement {
    handleButtonClick(event) {
        // Do whatever...
    }
}

代码重点:

eventHandler.html

  • 第2行:我们使用standardonclick 属性为标准click DOM事件指定处理程序。大括号{}表示事件处理程序是handleButtonClickJavaScript文件中的方法。

eventHandler.js

  • 第3行:我们定义了handleButtonClick处理程序,以接收event作为参数。

当您的处理程序需要访问事件所携带的状态或数据时,请使用事件对象。在这种情况下,您可以使用事件对象来查找将事件调度到的对象或单击事件的次数。我们将在本模块的后面部分详细讨论事件。

标准件

《 Visualforce开发人员指南》中的“ 标准组件参考”是标准Visualforce组件的库。同样,《 Lightning开发人员指南》 组件参考 是基础(标准)Lightning组件的库。

提示:要在参考中仅查看基础的Lightning Web组件,请展开“过滤器” ,然后 在“编程模型”下选择“ Lightning Web组件”。

使用基本组件快速轻松地开发应用程序。Salesforce维护基本组件,并创建您自动接收的新功能。

基础Lightning Web组件反映了Salesforce的外观。他们具有由Salesforce闪电设计系统(SLDS)提供的集成样式 。设计系统包括所有基本组件的蓝图以及可以在自己的组件中使用的CSS类。使用SLDS网站了解在构建自定义组件时适用的样式指导。

注意

一些基本组件已 开源。如果您需要的定制远远超出基本组件的允许范围,请克隆开源组件并将您自己的版本实现为定制组件。

要了解哪些基础Lightning Web组件与某些标准Visualforce组件相匹配,请参阅“资源”部分中的Visualforce标准组件和基础Lightning Web组件并排。

组成

在Visualforce中,您使用诸如<apex:component>和的标记<apex:include>来实现合成。当Visualforce页面包含Visualforce组件时,使用<apex:attribute>标签很容易将信息传递到该组件 。但是,将信息传递回页面涉及更复杂的模式,例如 Apex控制器的层次结构

Lightning Web组件中的组成相似。父级Lightning Web组件可以包括子级组件并与其通信。 

用户界面,其中“帐户搜索”组件包含“员工人数”输入字段组件。

简化了组成和通信机制,以便正确封装了每个组件的逻辑,并与其他组件进行松散耦合。

要将子组件包含在父组件中,请在kebab情况下使用子组件名称实例化该组件(是的,看起来像kebab),其后是其名称空间。自定义组件的默认名称空间是c。基本组件使用lightning名称空间。

在此示例中,contactTile定制组件和lightning-badge 基础组件作为compositionBasics组件的子代包括在内。

compositionBasics.html

<template>
    <c-contact-tile contact={contact}></c-contact-tile>
    <lightning-badge label="LWC rocks!"></lightning-badge>
<template>

要将信息从父组件传递到子组件,请使用 public属性 和 public方法@api在JavaScript文件中带有装饰器的属性或方法之前,会将其公开,以便其他组件可以访问它。要将信息从子级传递到其父级组件,请从标记中分派标准DOM事件或自定义事件(请参见 CustomEvent)。自定义事件不在此模块的范围内。父组件必须具有一个侦听事件的事件处理程序。让我们考虑一个示例,在该示例中,每当用户更改其值时,lightning-input 基本组件都会通知其父组件。

accountSearch.html

<template>
    <lightning-input
        type="number"
        label="Number of Employees"
        value={numberOfEmployees}
        onchange={handleChange}>
    </lightning-input>
</template>

accountSearch.js

import { LightningElement } from 'lwc';
export default class AccountSearch extends LightningElement {
    numberOfEmployees = null;
    handleChange(event) {
        this.numberOfEmployees = event.detail.value;
    }
}

代码重点:

accountSearch.html

  • 第2-7行:我们使用lightning-input 基本组件读取用户在输入字段中输入的值。lightning-input是的孩子c-account-search
  • 第5行:通过将父级属性绑定到子级属性,将numberOfEmployees属性值从c-account-search(父级组件)传递到lightning-input(子级组件)。我们可以执行此操作,因为基本组件具有名为的公共属性。numberOfEmployeesvaluelightning-inputvalue
  • 第6行:我们将一个名为处理程序handleChangechange事件绑定到该lightning-input组件触发的事件,将信息传递给父级。change标准的DOM事件。这是lightning-input组件将用户输入发送到的方式c-account-search

accountSearch.js

  • 第5行:我们从中读取用户输入event.detail.value

要了解有关这些通信模式的更多信息,请参阅Lightning Web Components基础 模块中的Lightning Web Components中的处理事件 。

适用于Visualforce开发人员的Lightning Web组件 – 闪电开发入门

学习目标

完成本单元后,您将能够:

  • 列出闪电组件框架的主要优点。
  • 说明如何同时使用低代码和专业代码工具来提高生产率。
  • 描述构成Lightning Web组件的标准,服务和文件。

嘿Visualforce开发人员,欢迎来到闪电体验!

如果您是经验丰富的Visualforce开发人员,并且希望使用最佳的Lightning Experience工具构建现代且引人入胜的用户体验,那么您将找到合适的位置。 

先决条件

为了充分利用本模块,您应该具有编写JavaScript的经验,并且了解JavaScript在Lightning Component框架中的作用。如果您尚未完成“ 学习使用JavaScript”路径,我们强烈建议您立即执行。

即使Visualforce仍可在Lightning Experience中运行,您仍可以使用Lightning Experience工具构建更无缝,引人入胜且响应迅速的用户体验。在本单元中,我们分享了我们为何开发Lightning Component框架,考虑为Lightning Experience开发用户界面的两种方法:低代码和前代码,并描述了Lightning Web组件的基础。

闪电体验和闪电组件框架

Visualforce为2006年的网络进行了设计和优化,基于与当时其他企业解决方案保持一致的技术堆栈。Visualforce的服务器端渲染可以满足当时的用户需求。 

但是,2006年之后,情况发生了变化。如今,用户期望获得更多的交互式,沉浸式和响应式的体验。为了满足这些要求,Salesforce推出了基于Lightning Component框架的Lightning Experience。 

开发人员不是使用Visualforce构建整体页面,而是创建小型的Lightning组件构建块,并以多种方式组装它们以创建不同的用户界面。 

闪电组件框架的优点包括:

  • 跨Salesforce的组件重用,最大限度地提高开发人员的生产力
  • 轻松扩展应用程序功能
  • 自定义组件:从AppExchange下载它们或创建自己的组件
  • 帮助您创建针对移动设备优化的响应式设计的构建器
  • 基本组件可在各种设备尺寸上正常工作

Lightning Experience中的UI开发:低代码和专业代码

Salesforce提供了两种在Lightning Experience中构建用户界面(UI)的方法:低代码和专业代码。 

  • 使用低代码点击工具来实现业务逻辑或构建用户界面。
  • 使用专业代码工具编写您自己的代码并完全自定义您的应用程序。

作为开发人员,当您开始开发新的东西时,您的直觉可能是立即开始编码。相反,请考虑使用低代码工具抢先一步。如果您使用低代码工具来进行重复的样板工作,那么您将有更多时间花在编码复杂需求上。另外,使用低代码工具构建的解决方案易于更改,并且可以通过低代码和专业代码工具进行扩展。

Salesforce中的UI开发

 

低码 专业密码
  • 闪电页
  • 快速行动
  • URL按钮
  • 工具栏
  • 流量
  • 闪电Web组件
  • 光环组件
  • 视觉力

如果您对Lightning Experience低代码解决方案不熟悉,我们强烈建议您通过获取这些Trailhead徽章来了解它们。

  • 闪电App Builder
  • 闪电体验定制
  • JavaScript按钮的替代闪电
  • Salesforce移动应用程序定制
  • 使用Flow Builder构建流程

对于专业代码工具,Salesforce提供了两个Lightning编程模型:Lightning Web Components和Aura Components。我们不会在这里深入研究它们,只是知道Lightning Web Components是在Lightning中开发自定义UI的首选方法。它性能更高,更易于构建且更易于移植。如果您想了解有关Aura组件和Lightning Web组件之间差异的更多信息,请阅读Trailhead上Lightning Experience Basics模块中的“了解Lightning Experience”单元 。

闪电Web组件基础知识

Lightning Web Components是基于Web组件标准的轻量级编程模型 。它抽象了Web组件API的更复杂的部分,并管理组件的生命周期,使您能够以更少的样板代码轻松编写组件。

闪电Web组件包含HTML,JavaScript和CSS。您学习编写Lightning Web组件的技能可以转移到任何其他基于JavaScript的技术上。 

Lightning Web组件由Lightning Locker服务隔离和固定 。Lightning Locker强制执行JavaScript 严格模式,提供 DOM访问限制,使用 全局对象的安全版本,并遵循内容安全策略(CSP)标准来防止代码注入攻击。 

注意:在继续之前,建议您阅读以下内容中的“发现闪电Web组件”。 模块。在这里,您将了解有关Lightning Web组件的基础以及构成Lightning Web组件的文件的更多信息。

适用于Aura开发人员的Lightning Web Components 与Event通信

学习目标

完成本单元后,您将能够:

  • 描述两种编程模型在事件上的差异。
  • 将事件从Lightning Web组件发送到Aura组件。

单独隔离的组件可能很有用,但是当组件开始相互交谈时,真正的应用程序魔术就会发生。这就是事件的源头。使用事件在组件之间进行通信是Web标准,而事件对于Aura组件和Lightning Web组件中的通信都是至关重要的。

组件事件成为DOM事件

将Aura组件中的组件事件迁移到Lightning Web组件中的Web标准DOM事件。如果您熟悉DOM事件,则会在Lightning Web组件中注意到相同的传播行为。

创建和发送事件

代替专有 事件 Aura组件中的对象,请使用 事件 要么 CustomEvent标准DOM接口。我们强烈建议您使用CustomEvent界面,因为这样可以提供更一致的体验。该框架可能需要修补事件的属性和方法,以规范浏览器之间的实现,并使用CustomEvent保证您的组件被覆盖。Internet Explorer不支持CustomEvent 接口本身,但Lightning Web组件模型增加了对此的支持。

Lightning Web组件中没有等效的 <aura:registerEvent>在Aura组件标记中标记,以注册组件可以触发事件。由于使用了标准的DOM事件,因此不需要额外的仪式。

代替 event.fire() 在Aura组件中,使用标准DOM方法, this.dispatchEvent(myEvent),在Lightning Web组件中。

这是在广告素材中创建和分配(触发)事件的示例 propertyTile 闪电网络组件。

export default class PropertyTile extends LightningElement {
    @api property;
    propertySelected() {
        const selectedEvent = new CustomEvent('selected', {
            detail: this.property.Id,
        });
        this.dispatchEvent(selectedEvent);
    }
}

中的第一个参数 CustomEvent() 构造函数将事件的名称设置为 已选

第二个参数是配置事件行为的对象。在此对象中,我们将详情,这是事件的数据有效负载。处理组件可以读取数据。在这种情况下,我们通过了this.property.Id 值。

处理事件

Aura组件使用 <光环:处理程序>在标记中标记以定义处理程序。另外,一个组件可以在其标记中引用另一个组件时声明一个处理程序动作。

此光环组件使用 c:孩子 在其标记中并声明一个 handleNotification 通知事件的处理程序 c:孩子 火灾。

<c:child notification="{!c.handleNotification}"/>

Lightning Web组件可以类似地具有声明性处理程序。声明处理程序中的事件名称以前缀

<c-child onnotification={handleNotification}></c-child>

的 handleNotification 事件处理函数在组件的JavaScript文件中定义。

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

让我们看看DreamHouse应用程序如何处理在 propertyTile闪电网络组件。的propertyTileList Lightning Web组件在其HTML文件中处理此事件。

<template for:each={properties} for:item="property">
    <c-property-tile property={property} key={property.Id} onselected={onPropertySelected}></c-property-tile>
</template>

的 已选 事件名称以开头  在由配置的声明处理程序中 onselected = {onPropertySelected}

的 onPropertySelected事件处理程序函数在propertyTileList.js中定义。

onPropertySelected(event) {
    pubsub.fire('propertySelected', event.detail);
}

让您回想起我们开除 已选 事件发生 propertyTile。的CustomEvent() 构造函数集 详情 至 this.property.Id。处理程序通过访问以下事件来解压缩事件数据事件细节。在此示例中,我们获得事件细节

我们解释发生了什么事 pubsub.fire() 接下来我们来看应用程序事件。

应用程序事件成为发布-订阅模式

将Aura组件中的应用程序事件迁移到Lightning Web组件中的发布-订阅(发布-订阅)模式。在发布-订阅模式中,一个组件发布一个事件,其他组件订阅以接收和处理该事件。订阅该事件的每个组件都会接收该事件。

标准DOM事件应该始终是您选择事件的首选,因为它们只会沿安全壳层次结构传播,从而使行为更加可预测。应用程序事件在复杂的应用程序中可能会出现问题,因为任何组件都可以处理该事件。由于组件的意外耦合,这种模式可能导致难以维护的代码。但是,有时您需要包含层次结构中的同级组件进行通信。Lightning页面或Lightning App Builder中使用的不相关组件是需要通信的同级组件的示例。在这些情况下,pub-sub模式是必经之路。

DreamHouse应用程序使用pubsub.js模块。随时复制pubsub 模块并在您的代码中使用它。

的 pubsub 模块导出三种方法。

寄存器
注册事件的回调。
取消注册
注销事件的回调。
向侦听器触发一个事件。

将事件发送到封闭的Aura组件

闪电Web组件调度DOM事件。封闭的Aura组件可以监听这些事件,就像封闭的Lightning Web组件一样。封闭的Aura组件可以捕获事件并进行处理。(可选)Aura组件可以触发Aura事件,以与其他Aura组件或与应用程序容器进行通信。

当您要支持Aura组件中使用但Lightning Web组件当前不支持的事件或接口时,此技术很有用。

以下示例说明了此技术。此Lightning Web组件触发自定义 通知 JavaScript文件中的事件。

// catchAndRelease.js
import { LightningElement } from 'lwc';
export default class CatchAndRelease extends LightningElement {
    /**
     * Handler for 'Fire My Toast' button.
     * @param {Event} evt click event.
     */
    handleFireMyToast(evt) {
        const eventName = 'notification';
        const event = new CustomEvent(eventName, {
            detail: { message: 'See you on the other side.' }
        });
        this.dispatchEvent(event);
    }
}

封闭的Aura组件包装器为自定义事件添加了处理程序。请注意,事件处理程序通知,将事件名称与 以它为前缀。即使用通知 处理名为 通知

<!-- catchAndReleaseWrapper.cmp -->
<aura:component implements="force:appHostable">
    <c:catchAndRelease onnotification="{!c.handleCustomEvent}"/>
</aura:component>

注意

注意

您只能指定一个 通知 DOM事件冒泡到的第一个Aura组件中的处理程序。

的 handleCustomEvent 在控制器的功能 catchAndReleaseWrapper Aura组件处理事件。

// catchAndReleaseWrapperController.js
({
    handleCustomEvent: function(cmp, evt) {
        // Get details from the DOM event fired by the Lightning web component
        var msg = evt.getParam('message') || '';
    }
})

Lightning Web组件调度的通知事件设置事件详细信息。

detail: { message: 'See you on the other side.' }

处理事件的Aura组件使用以下命令访问事件数据 evt.getParam(’message’)

您可以根据需要处理事件。您可以选择触发一个新的Aura事件,以与其他Aura组件进行通信。

适用于Aura开发人员的Lightning Web Components – 组成组件

学习目标

完成本单元后,您将能够:

  • 组成组件。
  • 使用插槽。
  • 列出两种编程模型的数据绑定行为之间的差异。

您可以在另一个组件的主体内添加组件。这种组件组成使您可以从更简单的构建块组件中构建复杂的组件。

在大型应用程序中,将应用程序与一组较小的组件组​​合在一起以使代码更易于重用和维护是很有用的。

的 闪电 命名空间包含许多基本组件,例如 闪电按钮,可用于构建组件。有关更多详细信息,请参见组件库

了解组件关系

让我们从一个简单的示例开始,然后定义一些我们用于组成组件的术语。讨论似乎是不必要的转移,但与其他开发人员交谈时保持一致的术语很重要。

<!-- owner.html -->
<template>
    <c-child first-name="Moonbeam"></c-child>
<template>

该HTML文件使用 <c-child>,指的是 儿童 组件中的 C命名空间。如果尚未为组织设置名称空间前缀,请使用默认名称空间C 引用您创建的组件时。

所有者
所有者是拥有模板的组件。在此示例中,所有者是c所有者组件。所有者控制它包含的所有组成组件。所有者可以:

  • 在组成的组件上设置公共属性。
  • 在组成的组件上调用公共方法。
  • 侦听由组成组件触发的任何事件。
父母与子女
当一个组件包含另一个组件(该组件又可以包含其他组件)时,我们具有一个包含层次结构。在文档中,有时我们讨论父组件和子组件。父组件包含子组件。父组件可以是所有者,也可以是所有者模板的一部分的容器组件。
在这个例子中 c-父容器 是容器组件,因为它包含 小孩。的c-父容器 组件不是所有者,因为它位于所有者组件的模板中, 业主

<!-- owner.html -->
<template>
    <c-parent-container>
        <c-child first-name="Moonbeam"></c-child>
    </c-parent-container>
<template>

梦之屋的例子

让我们看一个组成组件的例子。的PropertyTileList 光环组件包含 PropertyTile 零件。

<aura:component>
    ...
    <div class="slds-card">
        <lightning:layout horizontalAlign="center" multipleRows="true">
            <aura:iteration items="{!v.properties}" var="property">
                <lightning:layoutItem padding="around-small" size="12" smallDeviceSize="6" mediumDeviceSize="4" largeDeviceSize="3">
                    <c:PropertyTile property="{#property}"/>
                </lightning:layoutItem>    
            </aura:iteration>
        </lightning:layout>
    </div>
    
</aura:component>

的 PropertyTile 组件具有称为的属性 属性。不要被那个名字分散注意力。DreamHouse是一个房地产应用程序,因此我们在这里谈论房地产属性而不是JavaScript属性!

这是HTML的 propertyTileList 闪电网络组件:

<template>
    <div class="slds-card tile-list">
        <template for:each={filteredProperties} for:item="property">
            <c-property-tile property={property} key={property.Id}></c-property-tile>
        </template>
    </div>
</template>

对于这两种编程模型,标记看起来相似,除了用于引用组成的组件的语法外。前面我们看到了Aura模型和Lightning Web组件模型如何分别具有不同的语法来引用标记中的组件。

  • 在Aura组件中,我们使用 c:PropertyTile
  • 在Lightning Web组件中,我们使用 房地产。破折号分隔了命名空间,C,来自组件名称。骆驼案propertyTile 闪电Web组件被称为 物业平铺 在包含它的另一个Lightning Web组件的HTML文件中。

Lightning Web组件包含Lightning Web组件

让我们看一下包含两个Lightning Web组件lwcContainerComponent和lwcComponent的组成。

<!-- lwcContainerComponent.html -->
<template>
    <c-lwc-component></c-lwc-component>
</template>

要使用Lightning Web组件, lwcComponent,在另一个Lightning Web组件中:

  • 使用破折号分隔命名空间, C,来自组件名称。
  • 更改骆驼案的名称, lwcComponent,以kebab案例(破折号)为参考, LWC组件。为了与Web组件标准保持一致,我们使用破折号分隔的参考。
  • HTML规范要求自定义元素的标签不能自动关闭。自闭合标签以/>。Lightning Web组件本质上是一个自定义元素。因此,您需要打开和关闭标签以供组件参考:
    <c-lwc-component></c-lwc-component>

Aura组件包含一个闪电Web组件

现在,让我们看一下Aura组件auraWrapper,其中包含Lightning Web组件lwcContainerComponent。

<!-- auraWrapper.cmp -->
<aura:component>
    <c:lwcContainerComponent />
</aura:component>

要使用Lightning Web组件, lwcContainerComponent 在光环组件中:

  • 使用冒号分隔命名空间, C,来自组件名称。
  • 使用骆驼箱组件名称, lwcContainerComponent
  • Aura标记中允许使用自闭合标签,因此我们使用 <c:lwcContainerComponent />

刻面成为插槽

在Aura中,构面是任何类型的属性Aura.Component []。这只是您可以为属性设置一组组件的一种奇特的方式。用更不用说的话,可以将构面视为三明治。您可以根据需要将尽可能多的配料(成分)填充到三明治(构面)中。

例如,每个Aura组件都继承了一个 身体 属性,这是一个方面。构面的概念很重要,因为它使您可以设计具有属性的组件,该属性是父组件可以设置的标记的占位符。

闪电Web组件使用插槽代替刻面。插槽是Web组件规范的一部分

这是一个Aura组件的示例,其中包含一个 标头 方面和 身体 默认情况下,每个组件都有。

<aura:component>
    <aura:attribute name="header" type="Aura.Component[]"/>
    <div>
        <span>{!v.header}</span><br/>
        <span>{!v.body}</span>
    </div>
</aura:component>

类似的Lightning Web组件如下所示。

<template>
    <div>
        <slot name="header"></slot><br/>
        <slot></slot>
    </div>
</template>

插槽名为 标头 取代 标头方面。未命名的插槽取代了身体 方面。

您可以在《Lightning Web Components开发人员指南》中深入了解。

还有其他方面需要考虑的方面吗?

是的,我很高兴你问!请记住,Lightning Web组件不能包含Aura组件。如果要迁移包含构面的Aura组件,则还必须将要填充的所有子组件都迁移到构面中。这样,您可以确保永远不要将Aura组件放入Lightning Web组件中。

数据绑定差异

在标记中添加组件时,可以根据所有者组件的属性值在子组件中初始化公共属性值。两种编程模型的数据绑定行为是不同的。

Aura组件数据绑定

Aura组件可以使用两种形式的表达式语法进行数据绑定: {!expr} 要么 {#expr}。在这里我们将不讨论其中的差异,但让我们看一个简单的示例。

<!-- owner.cmp -->
<aura:component>
    <aura:attribute name="fName" type="String" />
    <c:child firstName="{!v.fName}"/>
</aura:component>

所有者组件传递其值 名称 属性添加到子组件中,这将导致两个组件之间的数据绑定(也称为值绑定)。

在Aura组件中,此数据绑定是两种方法。的变化名称 属性传递到子组件的 名字 属性,以及 名字 子组件中的属性传递回 名称所有者组件的属性。这种双向数据绑定对于性能而言可能是昂贵的,并且由于数据更改的传播而可能创建难以调试的错误,尤其是在您具有深层嵌套的组件的情况下。

Lightning Web组件数据绑定

在Lightning Web组件中,属性值的数据绑定是一种方法。如果属性值在所有者组件中更改,则更新后的值将传播到子组件。反之则不成立。

让我们看一个简单的数据绑定示例。

<!-- owner.html -->
<template>
    <c-child first-name={fName}></child>
</template>

数据绑定行为在Lightning Web组件中故意更简单且更可预测。子组件必须将从所有者组件传递的所有属性值都视为只读。如果子组件更改了从所有者组件传递的值,则会在浏览器控制台中看到错误。

为了触发所有者组件提供的属性值的突变,子组件可以将事件发送给父组件。如果父级拥有数据,则父级可以更改属性值,该属性值将通过单向数据绑定向下传播到子级组件。

适用于Aura开发人员的Lightning Web Components – 组成组件

学习目标

完成本单元后,您将能够:

  • 组成组件。
  • 使用插槽。
  • 列出两种编程模型的数据绑定行为之间的差异。

您可以在另一个组件的主体内添加组件。这种组件组成使您可以从更简单的构建块组件中构建复杂的组件。

在大型应用程序中,将应用程序与一组较小的组件组​​合在一起以使代码更易于重用和维护是很有用的。

的 闪电 命名空间包含许多基本组件,例如 闪电按钮,可用于构建组件。有关更多详细信息,请参见组件库

了解组件关系

让我们从一个简单的示例开始,然后定义一些我们用于组成组件的术语。讨论似乎是不必要的转移,但与其他开发人员交谈时保持一致的术语很重要。

<!-- owner.html -->
<template>
    <c-child first-name="Moonbeam"></c-child>
<template>

该HTML文件使用 <c-child>,指的是 儿童 组件中的 C命名空间。如果尚未为组织设置名称空间前缀,请使用默认名称空间C 引用您创建的组件时。

所有者
所有者是拥有模板的组件。在此示例中,所有者是c所有者组件。所有者控制它包含的所有组成组件。所有者可以:

  • 在组成的组件上设置公共属性。
  • 在组成的组件上调用公共方法。
  • 侦听由组成组件触发的任何事件。
父母与子女
当一个组件包含另一个组件(该组件又可以包含其他组件)时,我们具有一个包含层次结构。在文档中,有时我们讨论父组件和子组件。父组件包含子组件。父组件可以是所有者,也可以是所有者模板的一部分的容器组件。
在这个例子中 c-父容器 是容器组件,因为它包含 小孩。的c-父容器 组件不是所有者,因为它位于所有者组件的模板中, 业主

<!-- owner.html -->
<template>
    <c-parent-container>
        <c-child first-name="Moonbeam"></c-child>
    </c-parent-container>
<template>

梦之屋的例子

让我们看一个组成组件的例子。的PropertyTileList 光环组件包含 PropertyTile 零件。

<aura:component>
    ...
    <div class="slds-card">
        <lightning:layout horizontalAlign="center" multipleRows="true">
            <aura:iteration items="{!v.properties}" var="property">
                <lightning:layoutItem padding="around-small" size="12" smallDeviceSize="6" mediumDeviceSize="4" largeDeviceSize="3">
                    <c:PropertyTile property="{#property}"/>
                </lightning:layoutItem>    
            </aura:iteration>
        </lightning:layout>
    </div>
    
</aura:component>

的 PropertyTile 组件具有称为的属性 属性。不要被那个名字分散注意力。DreamHouse是一个房地产应用程序,因此我们在这里谈论房地产属性而不是JavaScript属性!

这是HTML的 propertyTileList 闪电网络组件:

<template>
    <div class="slds-card tile-list">
        <template for:each={filteredProperties} for:item="property">
            <c-property-tile property={property} key={property.Id}></c-property-tile>
        </template>
    </div>
</template>

对于这两种编程模型,标记看起来相似,除了用于引用组成的组件的语法外。前面我们看到了Aura模型和Lightning Web组件模型如何分别具有不同的语法来引用标记中的组件。

  • 在Aura组件中,我们使用 c:PropertyTile
  • 在Lightning Web组件中,我们使用 房地产。破折号分隔了命名空间,C,来自组件名称。骆驼案propertyTile 闪电Web组件被称为 物业平铺 在包含它的另一个Lightning Web组件的HTML文件中。

Lightning Web组件包含Lightning Web组件

让我们看一下包含两个Lightning Web组件lwcContainerComponent和lwcComponent的组成。

<!-- lwcContainerComponent.html -->
<template>
    <c-lwc-component></c-lwc-component>
</template>

要使用Lightning Web组件, lwcComponent,在另一个Lightning Web组件中:

  • 使用破折号分隔命名空间, C,来自组件名称。
  • 更改骆驼案的名称, lwcComponent,以kebab案例(破折号)为参考, LWC组件。为了与Web组件标准保持一致,我们使用破折号分隔的参考。
  • HTML规范要求自定义元素的标签不能自动关闭。自闭合标签以/>。Lightning Web组件本质上是一个自定义元素。因此,您需要打开和关闭标签以供组件参考:
    <c-lwc-component></c-lwc-component>

Aura组件包含一个闪电Web组件

现在,让我们看一下Aura组件auraWrapper,其中包含Lightning Web组件lwcContainerComponent。

<!-- auraWrapper.cmp -->
<aura:component>
    <c:lwcContainerComponent />
</aura:component>

要使用Lightning Web组件, lwcContainerComponent 在光环组件中:

  • 使用冒号分隔命名空间, C,来自组件名称。
  • 使用骆驼箱组件名称, lwcContainerComponent
  • Aura标记中允许使用自闭合标签,因此我们使用 <c:lwcContainerComponent />

刻面成为插槽

在Aura中,构面是任何类型的属性Aura.Component []。这只是您可以为属性设置一组组件的一种奇特的方式。用更不用说的话,可以将构面视为三明治。您可以根据需要将尽可能多的配料(成分)填充到三明治(构面)中。

例如,每个Aura组件都继承了一个 身体 属性,这是一个方面。构面的概念很重要,因为它使您可以设计具有属性的组件,该属性是父组件可以设置的标记的占位符。

闪电Web组件使用插槽代替刻面。插槽是Web组件规范的一部分

这是一个Aura组件的示例,其中包含一个 标头 方面和 身体 默认情况下,每个组件都有。

<aura:component>
    <aura:attribute name="header" type="Aura.Component[]"/>
    <div>
        <span>{!v.header}</span><br/>
        <span>{!v.body}</span>
    </div>
</aura:component>

类似的Lightning Web组件如下所示。

<template>
    <div>
        <slot name="header"></slot><br/>
        <slot></slot>
    </div>
</template>

插槽名为 标头 取代 标头方面。未命名的插槽取代了身体 方面。

您可以在《Lightning Web Components开发人员指南》中深入了解。

还有其他方面需要考虑的方面吗?

是的,我很高兴你问!请记住,Lightning Web组件不能包含Aura组件。如果要迁移包含构面的Aura组件,则还必须将要填充的所有子组件都迁移到构面中。这样,您可以确保永远不要将Aura组件放入Lightning Web组件中。

数据绑定差异

在标记中添加组件时,可以根据所有者组件的属性值在子组件中初始化公共属性值。两种编程模型的数据绑定行为是不同的。

Aura组件数据绑定

Aura组件可以使用两种形式的表达式语法进行数据绑定: {!expr} 要么 {#expr}。在这里我们将不讨论其中的差异,但让我们看一个简单的示例。

<!-- owner.cmp -->
<aura:component>
    <aura:attribute name="fName" type="String" />
    <c:child firstName="{!v.fName}"/>
</aura:component>

所有者组件传递其值 名称 属性添加到子组件中,这将导致两个组件之间的数据绑定(也称为值绑定)。

在Aura组件中,此数据绑定是两种方法。的变化名称 属性传递到子组件的 名字 属性,以及 名字 子组件中的属性传递回 名称所有者组件的属性。这种双向数据绑定对于性能而言可能是昂贵的,并且由于数据更改的传播而可能创建难以调试的错误,尤其是在您具有深层嵌套的组件的情况下。

Lightning Web组件数据绑定

在Lightning Web组件中,属性值的数据绑定是一种方法。如果属性值在所有者组件中更改,则更新后的值将传播到子组件。反之则不成立。

让我们看一个简单的数据绑定示例。

<!-- owner.html -->
<template>
    <c-child first-name={fName}></child>
</template>

数据绑定行为在Lightning Web组件中故意更简单且更可预测。子组件必须将从所有者组件传递的所有属性值都视为只读。如果子组件更改了从所有者组件传递的值,则会在浏览器控制台中看到错误。

为了触发所有者组件提供的属性值的突变,子组件可以将事件发送给父组件。如果父级拥有数据,则父级可以更改属性值,该属性值将通过单向数据绑定向下传播到子级组件。

适用于Aura开发人员的Lightning Web Components – 使用Salesforce数据

学习目标

完成本单元后,您将能够:

  • 使用基本组件创建用于处理单个记录的表单。
  • 使用有线服务获取数据。
  • 创建和更新数据。
  • 调用Apex方法。

没有任何数据的组件可能看起来不错,但内部感觉有些空白。在本单元中,我们填补了这一空白,并比较了Aura和Lightning组件如何读写Salesforce数据。

如果您为Aura组件开发了Apex类,则可以在Lightning Web组件中重用Apex。但是,由于在Lightning Web组件中使用数据的替代方法,您可能会发现不再需要Apex。

创建一个表单以处理单个记录

要创建允许用户查看,编辑和创建Salesforce记录的表单,Aura组件和Lightning Web组件都可以在 闪电 命名空间。

这些组件提供表单布局并处理记录的CRUD更改,而无需Apex代码。他们使用Lightning Data Service在各个组件之间缓存和共享记录更新。

Lightning Data Service构建在公共用户界面API之上,但仅支持API的子集。该子集涵盖了许多处理数据的典型用例。

这些组件的行为相同,但是具有命名约定的区别,这与我们之前在Aura组件和Lightning Web组件中看到的一样。

表格功能 灵气成分 闪电网络组件
支持编辑,查看和只读模式 闪电:记录形式 闪电记录形式
只读形式 闪电:recordViewForm 闪电记录视图形式
可编辑表格 闪电:recordEditForm 闪电记录编辑表

在大多数情况下, 闪电记录形式提供了一个很好的起点。它结合并简化了功能闪电记录视图形式 和 闪电记录编辑表

对于需要自定义字段布局和自定义呈现记录数据的更高级用例,请使用 闪电记录视图形式 和 闪电记录编辑表

这是一个例子 经纪人详细信息 灵气成分。

<lightning:recordForm
  objectApiName="Broker__c"
  recordId="{!v.property.Broker__c}"
  fields="{!v.brokerFields}"
  columns="2"/>

这是等效的HTML brokerCard 闪电网络组件。

<lightning-record-form
  object-api-name="Broker__c" 
  record-id={brokerId}
  fields={brokerFields} 
  columns="2">
</lightning-record-form>

自定义用户界面以处理单个记录

需要对UI进行更多控制的Aura组件 闪电:记录形式 和朋友提供可以使用 <force:recordData> 在标记中使用自己的自定义UI标记代码。

的 物业摘要 光环组件用途 <force:recordData> 在其标记中。

<force:recordData aura:id="service"
      recordId="{!v.recordId}"
      targetFields="{!v.property}"
      fields="['Id',
              'Thumbnail__c',
              'Address__c',
              'City__c',
              'State__c',
              'Zip__c',
              'Price__c',
              'Beds__c',
              'Baths__c',
              'Broker__r.Id',
              'Broker__r.Name',
              'Broker__r.Title__c',
              'Broker__r.Mobile_Phone__c',
              'Broker__r.Email__c',
              'Broker__r.Picture__c']" />

代替 <force:recordData>,Lightning Web组件有几种使用Lightning Data Service的技术,但是根据您是读取还是写入数据而有所不同。仅在以下情况下才考虑使用Wire Service和JavaScript API方法: 闪电记录*形式 组件不符合您的要求。

使用电汇服务获取数据

要读取Salesforce数据,Lightning Web组件使用基于Lightning Data Service构建的反应式线路服务。组件使用@线 在他们的JavaScript类中从其中的一个有线适配器读取数据 闪电/ ui * api命名空间。有关Salesforce提供的电线适配器的列表,请参阅本单元的“资源”部分。您不能编写自己的自定义线适配器。

我们之所以将有线服务称为响应式服务,部分原因是它支持响应式变量,该变量以$开头。如果电抗变量发生变化,则电汇服务将提供新数据。我们说“设置”而不是“请求”或“获取”,因为有线适配器而不是组件控制何时提供数据。

这是propertySummary.js中使用的示例@线 检索记录。

import { LightningElement, api, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Property__c.Name';
import PICTURE_FIELD from '@salesforce/schema/Property__c.Picture__c';
export default class PropertySummary extends LightningElement {
    @api recordId;
    propertyName;
    pictureURL;
    @wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD, PICTURE_FIELD] })
    wiredRecord({ error, data }) {
        if (data) {
            this.propertyName = getFieldValue(data, NAME_FIELD);
            this.pictureURL = getFieldValue(data, PICTURE_FIELD);
        } else if (error) {
            // Handle error. Details in error.message.
        }
    }
}

该代码导入 getRecord 电线适配器来自 lightning / uiRecordApi

当您使用 ui * Api线适配器,我们强烈建议导入对对象和字段的引用。导入对对象和字段的引用可确保您的代码正常工作,因为Salesforce会验证对象和字段是否存在。这行代码导入了对名称 中的字段 属性 自定义对象。

import NAME_FIELD from '@salesforce/schema/Property__c.Name';

的 @api 装饰使 recordId财产公开。包含的父组件 属性摘要 设置的值 记录编号 HTML文件中的属性。

因为 $ recordId 前面有一个 $,当其值更改时,有线服务将获取新数据并将其提供给组件。提供新数据时,将调用有线功能。该过程将更新属性,从而导致重新渲染。

的 有线录音函数从有线服务接收数据流。记录数据返回到数据论据。任何错误都将返回给错误 论据。

使用JavaScript API方法写入数据

的 createRecordJavaScript API创建一条记录。您也可以使用updateRecord 要么 deleteRecord。我们仍在使用Lightning Data Service,因此不需要Apex。

重要

不要使用 @线创建,更新或删除记录。有线服务将控制流委托给Lightning Web Components引擎。委派控制对于读取操作非常有用,但是对于创建,更新和删除操作却不是很好。作为开发人员,您希望完全控制更改数据的操作。这就是为什么您使用JavaScript API(而不是有线服务)执行创建,更新和删除操作的原因。

这是一个 ldsCreateRecord 使用的Lightning Web组件 createRecord 创建一个帐户。

import { LightningElement } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { createRecord } from 'lightning/uiRecordApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';
export default class LdsCreateRecord extends LightningElement {
    accountId;
    name;
    onNameChange(event) {
        this.name = event.target.value;
    }
    createAccount() {
        const recordInput = {
            apiName: ACCOUNT_OBJECT.objectApiName,
            fields: { 
                [NAME_FIELD.fieldApiName]: this.name, 
            }
        };
        createRecord(recordInput)
            .then(account => {
                this.accountId = account.id;
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Success',
                        message: 'Account created',
                        variant: 'success',
                    }),
                );
            })
            .catch(error => {
                // Handle error. Details in error.message.
            });
    }
}

createRecord 返回一个 诺言成功解决创建的记录的对象。有关JavaScript API的更多信息,请参见本单元末尾的参考资料。

的HTML文件 ldsCreateRecord 包括一个调用的按钮 创建帐号()在JavaScript文件中。帐户名称设置在雷电输入 零件。

<template>
    <lightning-card title="LdsCreateRecord" icon-name="standard:record">
        <div class="slds-m-around_medium">
            <lightning-input label="Id" disabled value={accountId}></lightning-input>
            <lightning-input label="Name" onchange={onNameChange} class="slds-m-bottom_x-small"></lightning-input>
            <lightning-button label="Create Account" variant="brand" onclick={createAccount}></lightning-button>
        </div>
    </lightning-card>
</template>

使用Apex进行自定义数据访问

我们已经研究了一些使用Lightning Data Service处理数据的技术。这些技术通常意味着更少的代码,因为您不需要任何Apex。但是,如果您已经具有为Aura组件开发的Apex代码,则可以在Lightning Web组件中重复使用它。或者,如果需要SOQL查询来进行自定义数据访问,则必须使用Apex方法。

要从Aura组件访问Apex控制器,请从JavaScript控制器或帮助器进行调用。这是物业轮播 光环组件调用 getPictures() Apex方法。

({
    loadPictures : function(component) {
        var propertyId = component.get("v.recordId");
        component.set("v.files", []);
        if (!propertyId) {
            return;
        }
        var action = component.get("c.getPictures");
        action.setParams({
            "propertyId": propertyId,
        });
        action.setCallback(this, function (response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var files = response.getReturnValue();
                component.set("v.files", files);
            }
            else if (state === "INCOMPLETE") {
                // handle incomplete state
            }
            else if (state === "ERROR") {
                // handle error state
            }
        });
        $A.enqueueAction(action);
    }
})

任何访问Salesforce数据的Aura组件都具有类似的样板。对于Lightning Web组件,访问Apex方法的语法不同。

闪电Web组件可以从Apex类导入方法。导入的方法是组件可以通过声明方式调用的函数@线 或直接在代码中。

将Apex方法公开给闪电Web组件

要将Apex方法公开给Lightning Web组件,该方法必须为 静态的 还有 全球 要么 上市。注释方法@AuraEnabled。这些要求与在Aura组件中使用Apex方法相同。的@AuraEnabled注解意味着您可以从Aura组件或Lightning Web组件调用方法。即使 @AuraEnabled 对于Lightning Web组件来说似乎是意外的,使用批注意味着您可以在两个编程模型中使用相同的Apex代码。

使用有线服务调用Apex方法

如果Apex方法是可缓存的(它不变异数据),则可以通过有线服务从组件调用它。您必须使用以下方法注释方法@AuraEnabled(cacheable = true)

注意

别 @线 创建,更新或删除数据的Apex方法。

让我们看一个 MyAccountController Apex控制器带有一个 getAccounts() 方法。

// MyAccountController.cls
public with sharing class MyAccountController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getAccounts() {
        return [SELECT Id, Name FROM Account
            WHERE AnnualRevenue > 1000000];
    }
}

此JavaScript代码称为Apex getAccounts() 使用有线服务的方法。

import { LightningElement, wire } from 'lwc';
import getAccounts from '@salesforce/apex/MyAccountController.getAccounts';
export default class HelloApexAccounts extends LightningElement {
    accounts=[];
    @wire(getAccounts, {})
    wiredAccounts({ error, data }) {
        if (error) {
            this.error = error;
        } else if (data) {
            this.accounts = data;
        }
    }
}

请注意导入语句的语法 getAccounts

import getAccounts from '@salesforce/apex/MyAccountController.getAccounts';
  • MyAccountController 是Apex类的名称
  • getAccounts 是个 @AuraEnabled 我们导入的方法

直接调用Apex方法

如果Apex方法更改(创建,更新或删除)数据,因此不可缓存,则必须直接在代码中调用该方法。

这是一个调用Apex的Lightning Web组件 getContactList() 方法。

import { LightningElement } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
export default class ApexContactList extends LightningElement {
    contacts;
    getContacts() {
        getContactList()
            .then(result => {
                this.contacts = result;
            })
            .catch(error => {
                // Handle error. Details in error.message.
            });
    }
}

import语句看起来与有线服务示例相同。但是,调用该方法的语法没有@线注解。代替, getContactList() 返回一个 诺言 通过联系人列表成功解决的对象。

使用外部API

在Lightning Web组件中使用外部API类似于Aura组件。默认情况下,您无法从Lightning Web组件中的JavaScript代码调用第三方API。将远程站点添加为CSP受信任站点,以允许JavaScript组件代码从该站点的域加载资产并向该域的域发出API请求。

Aura组件和Lightning Web组件在运行来自第三方站点的JavaScript代码方面具有相同的限制。要使用第三方库,您必须将库作为静态资源上载。