创建 Lightning Web 组件
学习目标
完成本单元后,您将能够:
- 描述每个组件文件的内容。
- 为 Lightning web 组件创建 JavaScript 方法。
- 在组件生命周期中使用生命周期钩子。
使用时间
假设您想要构建一个独立于 Salesforce 中特定对象的数据显示元素。ebikes 示例报表中的 productCard 组件就是一个很好的例子。让我们研究一下该卡片组件,并从头开始构建我们自己的版本,这样您便能够了解它是如何演变成一个名副其实的 Lightning web 组件的。当您构建组件的各个部分并探索更多示例时,您很快便能掌握相关基础知识。
升级到组织
在本单元中,我们使用带 Salesforce 扩展包的 Visual Studio Code 开发了一个 Lightning web 组件。
所需内容
如第一单元所述,您需要对 Salesforce DX 有所了解才能继续操作。若要完成本单元,您需要:
- 带有 Salesforce 扩展包的 Visual Studio Code (VS Code)
- Salesforce CLI
完成快速入门:Lightning Web 组件项目,以达成这些要求。
了解 HTML 文件
Lightning web 组件的 HTML 文件均包含 template(模板)标签。该 template(模板)标签包含定义组件结构的 HTML。让我们看一下 ebikes 存储库中简化版 productCard 组件的 HTML。
按照步骤将这些示例粘贴到 VS Code 中。
- 在 VS Code 命令面板中选择 SFDX: Create Project(SFDX:创建项目)来创建新项目。接受标准模板,并给项目起名为
bikeCard。
- 在 force-app/main/default 下,右击 lwc 文件夹,选择 SFDX: Create Lightning Web Component(SFDX:创建 Lightning Web 组件)。
- 输入
app作为新组件的名称。
- 按下 Enter,然后再次按 Enter 以接受默认
force-app/main/default/lwc。
- 将以下代码粘贴到 app.html 中(替换文件中现有的 HTML)。花括号
<template> <div> <div>Name: {name}</div> <div>Description: {description}</div> <div>Category: {category}</div> <div>Material: {material}</div> <div>Price: {price}</div> <div><img src={pictureUrl} alt={name}/></div> </div> </template>{}中的识别码被绑定到相应 JavaScript 类中的同名字段。
- 将以下代码粘贴到 app.js 中。
import { LightningElement } from 'lwc'; export default class App extends LightningElement { name = 'Electra X4'; description = 'A sweet bike built for comfort.'; category = 'Mountain'; material = 'Steel'; price = '$2,700'; pictureUrl = 'https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/ebikes/electrax4.jpg'; } - 保存文件。
现在让我们来看一个真实的例子。假设您想要显示数据,但加载需要一些时间,您不希望让用户知道发生了什么。您可以在模板中使用 lwc:if 和 lwc:else 条件指令来确定要渲染哪些视觉元素。
- 将以下代码粘贴到 app.html 中。在 HTML 文件中
ready的值为true之前,“display”div标签中的内容不会出现。<template> <template lwc:if={ready}> <div id="display"> <div>Name: {name}</div> <div>Description: {description}</div> <div>Category: {category}</div> <div>Material: {material}</div> <div>Price: {price}</div> <div><img src={pictureUrl} alt={name}/></div> </div> </template> <template lwc:else> <div id="waiting">Loading…</div> </template> </template> - 将以下代码粘贴到 app.js 中。这能保存我们的数据值并设置 3 秒计时器。3 秒后,应显示内容。(当然,这样做只是为了进行测试。)
import { LightningElement } from 'lwc'; export default class App extends LightningElement { name = 'Electra X4'; description = 'A sweet bike built for comfort.'; category = 'Mountain'; material = 'Steel'; price = '$2,700'; pictureUrl = 'https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/ebikes/electrax4.jpg'; ready = false; connectedCallback() { setTimeout(() => { this.ready = true; }, 3000); } } - 保存文件。
基本 Lightning Web 组件
现在,您不想从头开始构建所有组件。所以让我们来探讨一下如何使用基本 Lightning web 组件。当然,还有很多组件,包括字段类型、显示控制器、导航项等。所有这些都在组件引用中列出。
让我们将 Bike 的细节突出出来。在 app.html 文件中,用 lightning-badge 组件替换上一个例子中 material 和 category 的 div 标签。HTML 如下所示。
<template>
<template lwc:if={ready}>
<div id="display">
<div>Name: {name}</div>
<div>Description: {description}</div>
<lightning-badge label={material}></lightning-badge>
<lightning-badge label={category}></lightning-badge>
<div>Price: {price}</div>
<div><img src={pictureUrl} alt={name}/></div>
</div>
</template>
<template lwc:else>
<div id="waiting">Loading…</div>
</template>
</template>保存文件。
Steel 和 Mountain 这两个词便会作为徽章出现。就是这么简单。
组件构建结构
一个组件只需要一个具有相同名称的文件夹和文件。它们会根据名字和位置自动关联。

所有 Lightning web 组件都有一个命名空间,用连字符与文件夹名分开。例如,在默认命名空间 c 中,文件夹名为 app 的 Lightning web 组件的标记为 <c-app>。
但是,Salesforce 平台不允许在组件的文件夹名或文件名中使用连字符。如果组件的名字有多个单词,比如 mycomponent,该怎么办?您不能将文件夹和文件命名为 my-component,这里,我们提供一个更方便的解决方案。
采用驼峰式大小写命名法,将组件命名为 myComponent。采用驼峰式大小写命名法的组件文件夹名在标记中采用串式命名法。在标记中,若要引用文件夹名为 myComponent 的组件,请使用 <c-my-component>。
例如 LWC 示例报表的 viewSource 文件夹包含 viewSource 组件的文件。当 hello 组件引用 HTML 中的 viewSource 组件时,它使用 c-view-source。
很好!我们来看一下 JavaScript。
使用 JavaScript
这是让您领会奥妙的时刻。正如您到目前为止所看到的,JavaScript 方法定义了如何处理输入、数据、事件、状态变化等,以让组件能正常发挥作用。
Lightning web 组件的 JavaScript 文件必须包含以下代码,其中 MyComponent 是您为组件类分配的名称。
import { LightningElement } from 'lwc';
export default class MyComponent extends LightningElement {
}export 语句定义了一个可扩展 LightningElement 类的类。作为最佳实践,类的名称通常与 JavaScript 类的文件名相匹配,但这不是强制要求。
LWC 模块
Lightning Web 组件(ECMAScript 6 中引入了内置模块)使用模块来捆绑核心功能,并使其能在您的组件文件中被 JavaScript 访问。Lightning web 组件的核心模块是 lwc。
从 import(导入)语句开始模块,并指定组件要使用的模块功能。
import(导入)语句表示 JavaScript 使用了 lwc 模块中的 LightningElement 功能。
// import module elements
import { LightningElement} from 'lwc';
// declare class to expose the component
export default class App extends LightningElement {
ready = false;
// use lifecycle hook
connectedCallback() {
setTimeout(() => {
this.ready = true;
}, 3000);
}
}-
LightningElement是 Lightning web 组件的基类,使我们能够使用connectedCallback()。
-
connectedCallback()方法是生命周期钩子之一。在下一节中,您将了解有关生命周期钩子的更多信息。现在,当在文档对象模型 (DOM) 中插入组件时会触发该方法。在这种情况下,计时器会启动。
生命周期钩子
Lightning Web 组件提供了方法,使您的代码能够“钩住”组件生命周期中的关键事件。这些事件包括当一个组件被:
- 创建
- 添加至 DOM
- 在浏览器中渲染
- 遇到错误
- 从 DOM 中删除
使用回调方法响应这些生命周期事件中的任一个。例如,当将组件插入 DOM 中时,会调用 connectedCallback()。当将组件从 DOM 中删除时,会调用 disconnectedCallback()。
在我们用于测试条件渲染的 JavaScript 文件中,我们使用 connectedCallback() 方法,当将组件插入 DOM 中时会自动执行代码。代码等待 3 秒钟,然后将 ready 设置为 true。
import { LightningElement } from 'lwc';
export default class App extends LightningElement {
ready = false;
connectedCallback() {
setTimeout(() => {
this.ready = true;
}, 3000);
}
}另外,请注意我们使用了关键字 this。如果您写过 JavaScript,就应该很熟悉关键字的用法,就像在其他环境中使用它一样。JavaScript 中的 this 关键字指的是当前上下文的顶层。在此处,上下文就是这个类。connectedCallback() 方法为顶层的 ready 变量赋值。这是揭示 Lightning Web 组件如何帮助您将 JavaScript 功能引入开发的一个很好的示例。您可以在“资源”部分找到有关 this 具体信息的链接。
装饰器
在 JavaScript 中,装饰器经常用于修改一个属性或函数的行为。
若要使用装饰器,需要从 lwc 模块中导入它,并将其放在属性或函数之前。
import { LightningElement, api } from 'lwc';
export default class MyComponent extends LightningElement{
@api message;
}您可以导入多个装饰器,但是一个属性或函数只能有一个装饰器。例如,一个属性不能同时有 @api 和 @wire 装饰器。
Lightning Web 组件装饰器的例子包括:
-
@api:将字段标记为公共字段。公共属性定义组件的 API。在其 HTML 标记中使用该组件的 owner 组件可以访问该组件的公共属性。所有公共属性都是响应式的,这意味着框架会观察属性的更改。当属性值发生变化时,框架会做出反应并重新渲染该组件。
-
@track:告诉框架观察对象属性或数组元素发生的变化。如果发生变化,框架会重新渲染组件。所有字段都是反应式的。如果字段的值发生变化,并且该字段用于模板中,或者用于模板中所用属性的 getter 中,则框架会重新渲染该组件。您无需用
@track来装饰字段。仅当字段包含对象或数组,并且您希望框架观察对象属性或数组元素发生的变化时,才使用@track。如果您要更改整个属性的值,则无需使用@track。
-
@wire:为您提供了一种从 Salesforce 组织获取和绑定数据的简单方法。
下面是使用 @api 装饰器在一个组件 (app) 中渲染另一个组件 (bike) 的值的例子。文件结构如下所示:

app 组件使用以下 HTML。
<!-- app.html -->
<template>
<div>
<c-bike bike={bike}></c-bike>
</div>
</template>app 组件使用以下 JavaScript。
// app.js
import { LightningElement } from 'lwc';
export default class App extends LightningElement {
bike = {
name: 'Electra X4',
picture: 'https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/ebikes/electrax4.jpg'
};
}bike 组件使用以下 HTML。
<!-- bike.html -->
<template>
<img src={bike.picture} alt="bike picture" />
<p>{bike.name}</p>
</template>bike 组件使用以下 JavaScript。
// bike.js
import { LightningElement, api } from 'lwc';
export default class Bike extends LightningElement {
@api bike;
}学习进展很快,您已经能够使用 VS Code 中的一些代码。在下一单元中,我们将部署一些代码,并详细讨论组件的生存环境。
资源
- Lightning Web 组件开发人员指南:反应
- Lightning Web 组件开发人员指南:引用(包括 HTML 模板指令、装饰器等)
- MDN Web 文档:this
