持续学习中…
版本管理
V1.0.0
1. The Lightning Web Components Model
1.1 Web演变
2014 :lightning组件框架和Aura编程模型发布2019 :LWC发布lightning组件框架和Aura编程模型 :数据服务/UI组件/组件模型/模板/渲染优化/模块化/语言扩展/ES5/事件/标准元素/渲染LWC :专业服务/数据服务/UI组件/Web组件/模板/自定义元素/虚拟DOM/模块化/ES7/事件/标准元素/渲染
1.2 LWC
一个融合了web标准过去五年突破,用于构建lightning组件的新式编程模型 提供了一层基于核心堆栈之上的专门的salesforce服务 性能良好、安全性、Lightning数据服务、基于lightning组件 web标准 :web组件、模板、自定义元素、虚拟DOM、模块、ES7、事件、标准元素、渲染可以与Aura模型共存和交互
1.3Aura和LWC的互用性
相同 :安全性、Lightning数据服务、基于lightning组件、事件、标准元素、渲染不同 :
Aura :自定义组件模型、自定义模板、自定义组件、最佳渲染、自定义模块。自定义事件、ES5LWC :web组件、模板、自定义元素、虚拟DOM、模块、ES7、标准事件Aura和LWC :可以共存和互用;共享相同的高级服务;可以在同一页面上共存;共享最基础的lightning组件;共享相同的底层服务;Aura可以包含LWC但是LWC不能包含AuraOOTB : out-of-the-box 开箱即用
2. Creating Lightning Web Components
2.1 在VSCode定义一个LWC组件
命名规则
必须以小写字母开头 必须只包含字母数字和下划线字符 不能包含连字符(破折号) 命名空间必须是唯一的 不能包含空格 不能以下划线结尾 不能包含两个连续的下划线 文件夹和文件名必须有相同的前缀名 myComponent : myComponent.html/myComponent.js/myComponent.css/myComponent.js-meta.xml
2.2 文件构成
UI组件
必须:HTML、JS、Metadata 可选:CSS、SVG Icon 服务组件
2.3 客户端-服务端体系结构
2.4 基础UI组件-JS
import { LightningElement } from 'lwc'
export default class MyComponent extends LightningElemnt { }
LightningElement : 标准HTML元素的自定义包装器lwc :用于LWC的核心模块MyComponent :采用帕斯卡命名法
2.5 基础UI组件-HTML
< template> < c-my-component> c-my-component> template>
使用kebab-case命名法 模板元素用来声明可以在运行时被渲染的HTML的片段
2.6 基础UI组件-CSS
需要在组件包中被创建 和组件名称相同 使用标准的CSS语法 不像Aura,不需要使用.THIS
2.7 三种命名法则的应用场景
驼峰 :文件名、文件夹名、JS中的属性名帕斯卡 :JS中的类名kebab :HTML中的组件引用、HTML中的属性名
2.8 使用Lightning App Builder
配置文件myCoomponent.js-meta.xml
isExposed :设置为true,该组件才能在Lightning App Builder中使用targets :该组件可以被添加到哪种类型的Lightning页面中去 这两个是最基础的元数据
2.9 使用salesforce App生成密码
sfdx force:user:passwrd:generate 一般来说,你的用户在scratch org没有一个确定的密码,可以用以上的命令生成一个 选择sandbox作为连接
3. Styling Components
3.1 Styling LWC
LDS (lightning design system): 在salesforce mobile app/lightning experience/社区中运行的LWC自动可用CSS :在组件文件夹中创建一个样式表;样式表名称必须与组件名称相同;自动应用无需引入;作用域仅限当前组件(虚拟DOM)
3.2 在LWC中的CSS基础知识
在CSS文件中定义的自定义样式 注意 :
LWC CSS不需要.this关键字 支持.classname选择器 不支持#id选择器,因为在渲染模板的时候id值可能会被转换为全局唯一值 CSS作用域 :注意由于虚拟DOM,父组件的CSS样式不能影响到子组件:host选择器 :
父组件中应用子组件c-child,在子组件的CSS中去使用:host选择器可以去控制c-child的样式(并非使用c-child选择器) 再遇见的样式表可以向上延伸,也可以给自己的元素添加样式 在组件间共享CSS规则 :创建一个组件仅包含一个CSS文件,在其他组件的CSS文件中可以去导入这个共享CSS,@import ‘share.css’
3.3 应用 SLDS Classes
BEM (Block-Element-Modifier):块级元素修饰符Block : 表示一个组件(例如:.slds-button)Element : 表示一个组件的衍生物(例如:.slds-button__icon)Modifier : 表示一个组件或者一个元素的不同状态(例如:.slds-button_neutral)
3.4 使用SLDS Icons
icon-name=“categoryname: iconname” 类别名 :图标名
3.5 背景色和背景图片
icon-name=“categoryname: iconname” 类别名:图标名 方法一 :直接加class更改方法二 :使用lightning-card包裹需要改变的组件
4. Defining Component Properties
4.1 响应式属性
可以是公共或是私有 每次属性值更改的时候强制组件模板重新渲染
4.2 修饰符
@api :用于暴露ige公共的响应式属性@track :用于定义一个私有的响应式属性@wire :用于读取salesforce数据或者调用apex
4.3 公共属性
Api, track, wire修饰符必须从lwc模块引入 公共属性用@api标记
4.4 私有属性
没有修饰符的私有属性,仅能在被定义的组件class内使用 私有属性改变也会导触发组件的重新渲染
4.5 可追踪属性
使用@track去追踪一个私有属性,在它改变的时候会重新渲染该组件 不要过度使用@track,当你需要一个属性在其改变的时候重新渲染就追踪这个属性
4.6 getters/setters
getters : get是为属性进行值计算的函数setters : setter是一个属性值每次被赋值时执行一些逻辑的函数getters和setters可以被@api修饰
4.7 数据绑定
保持数据和UI单向或者双向同步的过程 在LWC中,属性值的数据绑定是单向的 双向绑定 :value={value} οnchange={handleChange},在handleChange里面this.value = even.target.value
4.8 定义属性和方法
每次响应式属性更新时,所有的getter方法都会重新求值(即使在getter中没有使用该响应式属性) 如果它使用响应式变量(前缀是$),wire服务就是响应式的
4.9 组件中的布尔值
输入一个没有值的属性名可以传递一个值为true的布尔值 不能直接去显示的传递一个false的值 但是可以直接不传不传默认是false
5. Handling DOM Events
LWC支持标准的DOM事件 自定义事件也可以被创建和分发
5.1 生命周期钩子
在组件实例生命周期的特定阶段触发的回调方法 大多数LWC生命周期钩子都内置于HTML自定义元素规范中 除了LWC新增的两个:renderedCallback() / errorCallback()
5.2 定义一个构造函数
Constructor() 是一个在组件实例化时执行的函数在Constructor定义之后必须有super()
5.3 HTML模板指令
指令是向HTML模板添加动态行为的特殊属性 for:each={array} 迭代数组并呈现列表for:item=“currentItem” 访问当前项for:index=“index” 访问当前项从0开始的索引if:true|false={expression} 有条件的呈现模板的DOM元素iterator:iteratorName={array} 对数组中的第一个或最后一个项应用特殊行为并呈现列表key={uniqueId} 通过为列表中的每一项分配唯一标识符来提升呈现性能
5.4 迭代数组
将for:each 指令添加到一个嵌套的模板template标签上,包含需要重复的元素 使用for:item 访问当前项 使用key标识唯一元素
5.5 connectedCallback函数
当组件被插入DOM,connectedCallback() 函数将被触发 它会从父级传到子级
5.6 constructor() vs connectedCallback()
除了 constructor 之外,可以在组件生命周期的任何阶段向主元素添加属性
5.7 父子组件生命周期钩子
P created -> p constructor -> p connectedCallback -> p render -> c constructor -> c connectedCallback -> c render -> c renderCallback -> p renderCallback
5.8 销毁组件生命周期钩子
P removed -> p disconnectedCallback -> c removed -> c disconnectedCallback
5.9 常见生命周期钩子用例
constructor : 初始化,计算私有属性connectedCallback : 注册事件监听器,运行需要访问@api属性的逻辑,在主元素访问DOM属性disconnectedCallback : 注销事件监听器render : 有条件的渲染模板renderedCallback : 初始化第三方JSerrorCallback : 创建一个错误边界组件,捕获其树中所有后代组件中的错误
6. Debugging Lightning Web Components
6.1 lightning组件框架模式
6.2 如何打开调试模式
方式一 方式二 方式三 :这段代码存在于EXFiles/data/CreateUsers.txt中,它运行在scratch org创建脚本末尾的一个匿名Apex块中
自定义格式查看proxy类型的数据 :谷歌开发者工具->设置->打开自定义格式编程式断点 :在代码中加入debugger设置断点通过控制台逐步执行代码 :F8恢复执行;F10跳过函数调用;F11进入下一个函数调用;shift+F11退出当前函数;禁用断点;使用GitLens进行分支比较 :查看所有提交;查看所有文件修改;单机一个文件查看累积的更改;
6.3 编写测试
导入createElement和要测试的组件 新增一个describe 新增一个afterEach方法在测试结束的时候重置DOM 添加一个it来描述一个单次测试 创建被测试的组件 将组件添加到DOM 使用expect新增一个声明
7. Working with Salesforce Data
7.1 数据服务
两种方式 :UI API 和 apex ,都是去salesforce上面取数据UI API是用它已有的方法去取数据uirecordapi,不需要在apex额外写方法去获取数据 salesforce里面的object都有一个recordid是唯一的,可以通过这个去查数据,但是一次只能查一条,apex可以查多个recordid(也可以查一个,但是一般用来查多个) uirecordapi只能读单独一条数据 因为他只能接受一个recordid 如果多条就要写api 用soql 去取
7.2 使用lightning/uiRecordApi
getRecord : 使用wire声明,获取一条记录数据getFieldValue : 返回原始表的字段数据getFieldDisplayValue :根据本地设置返回格式化和本地化的字段数据可以使用这个语法获取原始字段值:record.data.fields.fieldname.value
7.3 Wire Service
可以使用Apex class或uiRecordApi读取数据 修饰一个属性或者方法 只读,没有DML操作(DML操作被阻止)
@wire(parameters) wiredMethodName
将apex方法暴露给LWC :这个方法必须用@AuraEnabled;必须是puclic或者global;必须是static
启用客户端缓存 :@AuraEnabled(cacheable =true) 通过在客户端缓存方法的结果可以提升性能;只能用于获取数据,不能改变数据(不能update或者delete数据);通过@wire service调用apex方法的时候必须设置(cacheable=true) !!!
可以用一个对象接收或者两个参数接收wiredContact(result) / wiredContact({ error, data })
Wire service run
属性 :在组件构造之后,在任何其他生命周期事件之前,会分配一个默认值(data和errorproperties都是undefined)
方法 :只要值可用,方法会在组件渲染之前或者之后被调用
如果一个响应变量(前缀为$)更改,wire service提供新数据
如果数据在客户端有缓存,则可能不会发送网络请求
8. Using Base Lightning Components
8.1
属性没有双向绑定 模板字符串允许嵌入表达式 `${ 表达式 }`
9. Raising and Handling Events
9.1 组件通信:子传父
< c- lwc- child onsampleevent= { handleSampleEvent} >
handleSampleEvent ( event ) {
alert ( JSON . stringify ( event. detail) ) ;
}
< lightning- button label= "Click Me" onclick= { sendEvent} >
sendEvent ( ) {
const selectedEvent = new CustomEvent ( 'sampleevent' , {
detail : { author : "Rad" , instructor : "EL Toro" }
} ) ;
this . dispatchEvent ( selectedEvent) ;
}
9.2 事件监听器
connectedCallback ( ) {
this . template. addEventListener ( 'onsampleevent' , this . handleSample . bind ( this ) ) ;
}
handleSample ( event ) {
alert ( 'handle the sample event programmatically' ) ;
}
9.3 组件通信:父传子
方法一 :通过在HTML添加属性给子组件传递参数, 子组件通过@api 属性名拿到方法二 :调用子组件的公共方法,通过querySelector拿到子组件DOM,调用子组件的方法用@api修饰 querySelector : 返回匹配名字的第一个元素
import { LightningElement, api } from 'lwc' ;
export default class StudentTiles extends LightningElement {
@api studentList;
}
< template for : each= { studentList} for : item= "student" >
< c- student- tile student= { student} key= { student. Id} > < / c- student- tile>
< / template>
import { LightningElement, api } from 'lwc' ;
export default class StudentTile extends LightningElement {
@api student;
}
< lightning- button variant= "natural" label= "Unselect Student" onclick= { handleUnselectStudent} > < / lightning- button>
< c- student- tiles student- list= { students. data} onstudentselected= { handleNotify} > < / c- student- tiles>
handleUnselectStudent ( ) {
this . template. querySelector ( 'c-student-tiles' ) . unselectStudent ( ) ;
}
@api unselectStudent ( ) {
this . selectedStudentId = "" ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
9.4 MIXIN
Mixin允许我们在不扩展类的情况下向类添加功能 当一个类已经扩展了父类的时候很有用 因为一个类只能扩展一个父类
9.5 Navigation Service
引入lightning/navigation 在你的组件基础类上应用NavigationMixin function 请求navigation service的[NavigationMixin.Navigate] function去分发navigation的请求,以及打开新的Course Delivery modal对话框
10. Advanced Communication between Components
10.1 虚拟DOM
DOM 树在虚拟DOM里面 LWC使用的虚拟DOM在谷歌开发者工具中看不到 虚拟DOM封装了每个LWC组件,并且他影响着我们如何使用CSS、事件和DOM
10.2 事件传播
bubbles (布尔):表明该事件是否会经过该DOMComposed (布尔):表明该事件是否会经过该虚拟DOM
10.3 配置bubbles和composed
const selectedEvent = new CustomEvent ( 'studentselected' , {
bubbles : true ,
composed : true ,
detail : { studentId : this . student. Id }
} ) ;
10.4 事件重定向
对于穿过虚拟DOM边界的冒泡事件,Event.target的值更改为匹配监听器作用域的DOM 监听器不能看到被分发给这个事件的组件的虚拟DOM 事件重定向以及scoped CSS保留了虚拟DOM的封装性
10.5 组件通信:不同的DOM树
Publish/subscribe(老的模式,新的使用messagechannel) 不在同一个DOM树的组件使用Pub-Sub 模式 针对Lighting app 页面的频繁架构 注意 :当标准的兄弟页面通信机制可行时,这个模式会被更新
10.6 组件通信:通过Pub-Sub
组件A通过fireEvent传递数据 组件B通过registerListener接收数据
单元总结
组件框架基于web标准 LWC由一个多文件包 组成,用于实现通过声明式标签实现对浏览器的DOM输出 用JS处理客户端事件,对组件进行样式化,并通过Lightning App Builder进行表面处理 响应式属性强制组件在每次值更新的时候重新渲染 LWC使用基于Lightning Data Service构建的响应式有线服务来读取salesforce数据
单元Review
列出LWC中的不同文件,以及何时使用每个文件。 描述从父组件调用子组件的语法。 配置文件的目的是什么? 不属于同一棵DOM树的组件之间的通信方式是什么? 我们什么时候使用Apex方法来处理Salesforce数据?