• 【salesforce】Lightning Web Component Study Log —— Part 2


    持续学习中…

    文章目录

    版本管理

    V1.0.0

    • 2022-11-17

    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:自定义组件模型、自定义模板、自定义组件、最佳渲染、自定义模块。自定义事件、ES5
      • LWC:web组件、模板、自定义元素、虚拟DOM、模块、ES7、标准事件
      • Aura和LWC:可以共存和互用;共享相同的高级服务;可以在同一页面上共存;共享最基础的lightning组件;共享相同的底层服务;Aura可以包含LWC但是LWC不能包含Aura
      • OOTB: 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
    • 服务组件
      • 必须:JS、Metadata

    2.3 客户端-服务端体系结构

    在这里插入图片描述

    2.4 基础UI组件-JS

    import { LightningElement } from 'lwc'
    export default class MyComponent extends LightningElemnt {}
    
    • 1
    • 2
    • LightningElement: 标准HTML元素的自定义包装器
    • lwc:用于LWC的核心模块
    • MyComponent:采用帕斯卡命名法

    2.5 基础UI组件-HTML

    <template><c-my-component>c-my-component>template>
    
    • 1
    • 使用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: 初始化第三方JS
    • errorCallback: 创建一个错误边界组件,捕获其树中所有后代组件中的错误

    6. Debugging Lightning Web Components

    6.1 lightning组件框架模式

    在这里插入图片描述

    6.2 如何打开调试模式

    1. 方式一
      在这里插入图片描述
    2. 方式二
      在这里插入图片描述
    3. 方式三:这段代码存在于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 APIapex,都是去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

    1. 可以使用Apex class或uiRecordApi读取数据
    2. 修饰一个属性或者方法
    3. 只读,没有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 组件通信:子传父

    • 默认情况,自定义事件只会向上冒泡一个层级
    // parent
    <c-lwc-child onsampleevent={handleSampleEvent}> // 这里是on开头
    handleSampleEvent(event) { 
    	alert(JSON.stringify(event.detail));
    }  // 注意:这里必须是detail
    
    // child
    <lightning-button label="Click Me" onclick={sendEvent}>
    sendEvent() { 
    	const selectedEvent = new CustomEvent('sampleevent', {  // sampleevent必须是小写
    		detail: { author: "Rad", instructor: "EL Toro" } 
    	}); 
    	this.dispatchEvent(selectedEvent);
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    9.2 事件监听器

    connectedCallback() {
    	this.template.addEventListener('onsampleevent', this.handleSample.bind(this));
    } 
    handleSample(event) { 
    	alert('handle the sample event programmatically');
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    9.3 组件通信:父传子

    • 方法一:通过在HTML添加属性给子组件传递参数, 子组件通过@api 属性名拿到
    • 方法二:调用子组件的公共方法,通过querySelector拿到子组件DOM,调用
    • 子组件的方法用@api修饰
    • querySelector: 返回匹配名字的第一个元素
    // 方法一
    // parent
    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> 
    
    // child
    import { LightningElement, api } from 'lwc'; 
    export default class StudentTile extends LightningElement { 
    	@api student; 
    }
    
    // 方法二
    // parent
    <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();
    }
    // child
    @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(布尔):表明该事件是否会经过该DOM
    • Composed(布尔):表明该事件是否会经过该虚拟DOM

    10.3 配置bubbles和composed

    const selectedEvent = new CustomEvent('studentselected', { 
    	bubbles: true, 
    	composed: true, 
    	detail: { studentId: this.student.Id } 
    }); 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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数据?
  • 相关阅读:
    【游戏建模全流程】ZBrush生物模型雕刻教程:豹纹壁虎
    DataX 自学使用
    【C++心愿便利店】No.8---C++之重识类和对象
    72:第六章:开发文章服务:5:开发【发表文章,接口】;
    【每日一题】—— C. Anonymous Informant(Codeforces Round 908 (Div. 2))(思维题)
    tcpip.sys是什么文件,tcpip.sys蓝屏的解决办法
    命令行获取chrome版本的多个方法
    Vue3从入门到精通(一)
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
    一面惨败网易经历,奋发图强一个月,终于成功上岸!
  • 原文地址:https://blog.csdn.net/qq_37604640/article/details/127902478