组件生命周期

Lightning Web 组件的生命周期由框架管理。框架创建组件,将它们插入到 DOM 中,呈现它们,然后将它们从 DOM 中删除。它还监视组件的属性更改。

生命周期流程

此图显示了从创建到渲染的组件生命周期流程。

此图显示了从 DOM 中删除组件实例时发生的情况。

创建组件时运行代码

该方法在创建组件实例时触发。不要在构造过程中向 host 元素添加属性。您可以在任何其他生命周期挂钩中向 host 元素添加属性。constructor()

构造函数从父级流向子级。

构造函数注意事项

HTML: Custom elements 规范中的这些要求适用于 .constructor()

  • 第一个语句必须不带参数。此调用为 建立正确的原型链和值。在触摸之前务必先打电话。super()thissuper()this
  • 不要在构造函数主体中使用语句,除非它是简单的提前返回 ( 或 )。returnreturnreturn this
  • 不要使用 or 方法。document.write()document.open()
  • 不要检查元素的属性和子元素,因为它们尚不存在。
  • 不要检查元素的公共属性,因为它们是在创建组件后设置的。

不要在构造过程中向主机元素添加属性

您可以在组件生命周期的任何阶段(构造除外)向主机元素添加属性。

不建议使用此模式,因为它会向 host 元素添加一个属性。constructor()

// don't do this
import { LightningElement } from "lwc";
export default class Deprecated extends LightningElement {
  constructor() {
    super();
    this.classList.add("new-class");
  }
}

若要向 host 元素添加属性,请改用该方法。connectedCallback()

import { LightningElement } from "lwc";

export default class New extends LightningElement {
  connectedCallback() {
    this.classList.add("new-class");
  }
}

在 DOM 中插入或删除组件时运行代码

当组件插入到 DOM 中时,生命周期钩子会触发。当组件从 DOM 中删除时,生命周期挂钩会触发。connectedCallback()disconnectedCallback()

两个钩子都从父级流向子级。您无法从回调访问子元素,因为它们尚不存在。要访问 host 元素,请使用 .要访问组件模板中的元素,请使用 .thisthis.template

用于与组件的环境进行交互。例如,使用它来:connectedCallback()

  • 与当前文档或容器建立通信,并协调与环境的行为。
  • 执行初始化任务,例如获取数据、设置缓存或侦听事件
  • 订阅和取消订阅消息通道。

钩子是使用传递给组件的初始属性调用的。如果组件从属性派生其内部状态,则最好在 setter 中编写逻辑,而不是在 中编写逻辑。有关示例代码,请参阅 Salesforce 工程师 Pierre-Marie Dartus 撰写的这篇 StackExchange 文章。connectedCallback()connectedCallback()

钩子可以发射不止一次。例如,如果删除一个元素,然后将其插入到另一个位置,例如在对列表重新排序时,挂钩会触发几次。如果希望代码运行一次,请编写代码以防止其运行两次。connectedCallback()

用于清理 中完成的工作,例如清除缓存或删除事件侦听器。disconnectedCallback()connectedCallback()

要检查组件是否连接到 DOM,可以使用 this.isConnected

在组件呈现时运行代码

这是 Lightning Web 组件所独有的。使用它在组件完成渲染阶段后执行逻辑。renderedCallback()

此挂钩从子级流向父级。

当组件呈现时,将重新计算模板中使用的表达式。

连接并渲染组件后,对组件状态的更改(或突变)会将组件标记为脏组件,并将微任务排入队列以重新渲染组件。有关跟踪哪些更改的详细信息,请参阅反应性。

在应用程序的生命周期中,组件通常会呈现多次。要使用此钩子执行一次性操作,请使用布尔字段 like 来跟踪是否已执行。第一次执行时,执行一次性操作并设置 .如果 ,则不执行该操作。hasRenderedrenderedCallback()renderedCallback()hasRendered = truehasRendered = true

最好在 HTML 模板中以声明方式添加事件侦听器。但是,如果确实需要以编程方式向模板元素添加事件侦听器,请在 中执行此操作。您无需删除侦听器。如果将侦听器重复添加到同一元素中,浏览器将忽略重复项。renderedCallback()

重新呈现模板时,LWC 引擎会尝试重用现有元素。在以下情况下,引擎使用差异算法来决定是否丢弃元素。

  • 使用 for:each 指令创建的元素。重用这些迭代元素的决定取决于属性。如果发生更改,则元素可能会被重新呈现。如果未更改,则不会重新呈现元素,因为引擎假定迭代元素未更改。keykeykey
  • 作为槽内容接收的元素。引擎尝试重用 中的元素,但差异算法确定是否逐出元素并重新创建它。<slot>

更新组件的状态可能会导致无限循环。例如:renderedCallback()

  • 不要更新 中的电线适配器配置对象属性。请参阅了解 Wire Service。renderedCallback()
  • 不要更新 中的公共属性或字段。请参阅反应性。renderedCallback()

提示

lwc-recipes samples 存储库中的模块使用 lifecycle hook。libsChartjsrenderedCallback()

处理组件错误

这是 Lightning Web 组件所独有的。实现它以创建一个错误边界组件,该组件捕获其树中所有后代组件中的错误。它捕获在后代的生命周期挂钩中或在 HTML 模板中声明的事件处理程序期间发生的错误。您可以对错误边界组件进行编码,以记录堆栈信息并呈现替代视图,以告知用户发生了什么以及下一步要做什么。errorCallback()

您可以创建错误边界组件,并在整个应用中重复使用它。由您决定在哪里定义这些错误边界。您可以包装整个应用程序,也可以包装每个单独的组件。最有可能的是,你的架构介于两者之间。想一想你想在什么地方告诉用户出了问题。

<!-- boundary.html -->
<template>
  <template lwc:if={error}>
    <error-view error={error} info={stack}></error-view>
  </template>
  <template lwc:else>
    <healthy-view></healthy-view>
  </template>
</template>
// boundary.js
import { LightningElement } from "lwc";
export default class Boundary extends LightningElement {
  error;
  stack;
  errorCallback(error, stack) {
    this.error = error;
  }
}

参数是 JavaScript 本机错误对象,参数是字符串。errorstack

您不必在模板中使用。例如,假设您定义了一个组件模板。如果此组件引发错误,框架将在重新渲染期间调用并卸载该组件。lwc:[if|elseif|else]errorCallback

<!-- boundary.html -->
<template>
  <my-one-and-only-view></my-one-and-only-view>
</template>