LWC的生命周期负责创建, 插入组件到DOM中, 并将其渲染和从DOM中删除. 它还监控已渲染的组件的任何属性变化, Lifecycle钩子其实是一种回调方法, 在组件实例的生命周期的特定阶段被触发. 下面为大家介绍LWC的几个生命周期Hooks.
1. Constructor()
当一个组件的实例被创建时, constructor()被调用. 在这个阶段, 我们不能访问组件的公共属性(@api 修饰), 因为它们还不存在, 如果我们在组件中包含了一个子组件, 那么我们也不能访问子组件的元素, 因为LWC的生命周期流程是从父组件到子组件. 也就是说, 子组件将在父组件被渲染后被渲染.下面的例子显示了我们如何在LWC文件中使用constructor函数.
1
2
3
4
5
6
7
import { LightningElement } from "lwc";
export default class ParentChildDemo extends LightningElement {
constructor() {
super(); // calling constructor of LightningElement
}
}
作为一个必要的步骤,我们需要从构造函数()中调用super()关键字.因为每个LWC组件都扩展了LightningElement,而LightningElement有它的构造函数,我们不应该绕过调用父类的构造函数.
我们可以从构造函数中设置值,但最好的做法是使用getter和setter方法来获取或设置变量的值.请参考下面的例子来更好地理解它.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { api, LightningElement } from "lwc";
export default class ParentChildDemo extends LightningElement {
variable1;
variable2;
constructor() {
super();
this.variable1 = "value";
}
@api
get item() {
return this.variable2;
}
set item(value) {
this.variable2 = value.toUpperCase();
}
}
对于构造函数,有一些注意事项.
DO’s
- 设置属性的值, 也可以定义变量.
- 可以调用 Apex Method
- 可以调用UI APIs, 比如 uiRecordApi
DON’T
- 不要试图访问元素的属性,因为它们还不存在.
- 不能从构造函数中create和dispatch custom events, 比如show toast message
2. ConnectedCallback()
当组件被插入到DOM中时, 它被调用. 当这个方法被执行的时候, 所有的公共属性都已经从它们的父组件那里得到了值. 在这个方法中, 我们可以调用需要将公共属性作为参数的Apex方法, 因为现在公共属性已经存在了.
如果我们想在组件被加载到DOM后执行任何种类的逻辑,我们可以使用connectedCallback()生命周期方法.
1
2
3
4
5
6
7
8
9
10
11
12
13
import { LightningElement, api } from "lwc";
export default class ParentChildDemo extends LightningElement {
@api publicProperty;
constructor() {
super();
}
connectedCallback() {
console.log("Now We can access public property: " + this.publicProperty);
}
}
要检查组件是否连接到DOM,我们可以使用isConnected属性,如果组件连接了,则返回真,否则返回假.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { LightningElement } from "lwc";
export default class ParentChildDemo extends LightningElement {
constructor() {
super();
let elmt = this.template;
console.log("From constructor: " + elmt.isConnected); // output: false
}
connectedCallback() {
let elmt = this.template;
console.log("From connectedCallback: " + elmt.isConnected); // output: true
}
}
对于connectedCallback函数,有一些注意事项.
DO’s
- 可以触发一个Custom Event.
- 可以调用 UI APIs & navigation service
- 订阅/取消订阅一个message channel
- 可以访问组件的元素
DON’T
- 还不能访问任何子组件的元素, 因为这时候子组件还不存在.
3. renderedCallback()
renderedCallback是LWC特有的,其他的都是HTML custom elements规范.由于这个钩子在组件的每次渲染后都会被调用,所以应该对它进行保护,以避免触发无限的渲染循环.当一个属性的值发生变化时,一个组件会被rendered.
下面的示例展示了renderedCallback是如何工作的
我们现在有两个组件: parentLwc 和 childLwc.
parentLwc.html
1
2
3
<template>
<c-child-lwc></c-child-lwc>
</template>
parentLwc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
import { LightningElement } from "lwc";
export default class ParentLwc extends LightningElement {
constructor() {
super();
}
connectedCallback() {}
renderedCallback() {
console.log("renderedCallback() Called From Parent component.");
}
}
childLwc.html
1
2
3
<template>
<h1>I'm child component</h1>
</template>
childLwc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
import { LightningElement } from "lwc";
export default class ChildLwc extends LightningElement {
constructor() {
super();
}
connectedCallback() {}
renderedCallback() {
console.log("renderedCallback() Called From Child component.");
}
}
Output logs:
1
2
// renderedCallback() Called From Child component.
// renderedCallback() Called From Parent component.
renderedCallback()方法被多次调用, 导致页面的无用渲染, 为了确保renderedCallback()只在需要的时候被调用, 我们可以使用私有布尔属性来判断.
DO’s
- 在一个组件完成渲染阶段后执行业务逻辑.
- 访问组件元素
- 调用 Apex, UI APIs, navigation service
- 创建 和 Dispatch custom events
DON’T
- 不要使用renderedCallback()来改变一个正在设置属性值的组件的状态,可以使用getter和setter.
- 不能在renderedCallback()中更新一个wire adapter配置的对象的属性,因为这会导致无限循环.
- 不要在renderedCallback()中更新一个reactive属性或字段,因为这可能会导致无限循环。
4. disconnectedCallback
当一个组件被从DOM中移除时,它就会被执行。它是编写组件被销毁或从DOM中移除后需要实现的逻辑的最佳位置。
1
2
3
4
5
6
7
8
9
10
11
import { LightningElement } from "lwc";
export default class ParentChildDemo extends LightningElement {
constructor() {
super();
}
disconnectedCallback() {
console.error("disconnectedCallback() Called From Parent component.");
}
}
DO’s
- 移除缓存
- 移除事件监听器
- 取消订阅LMS channels
5. errorCallback(error, stack)
在生命周期阶段,当所有子组件出现故障或错误时,它将被执行。它是LWC独有的,其余的都来自HTML规范。通过这个钩子,我们可以给我们的组件设置一个错误边界。 它可以帮助我们记录堆栈信息,并在子组件中遇到错误时渲染一个替代模板。这样,用户就可以知道到底发生了什么,接下来该怎么做。
它类似于javaScript的catch{}块,用于在子组件生命周期钩子中抛出错误的组件。是的,错误边界组件只抓取来自子组件生命周期钩子的错误,而不是来自它自己。
它需要两个参数:error和stack。error是一个javaScript本地错误对象,stack是一个字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { LightningElement } from "lwc";
export default class ParentChildDemo extends LightningElement {
error;
stack;
constructor() {
super();
}
errorCallback(error, stack) {
console.error("errorCallback() Called From Parent component.")
this.error = error;
this.stack = stack;
}
}