Web Component 教程(三):生命周期方法的触发时机与实际应用

前言

Web Components 是一种可以创建可复用、封装良好的 HTML 标签的技术,它使得我们可以像使用原生 HTML 标签一样使用自定义组件。在 Web Components 中,生命周期方法是关键,它们定义了组件在不同阶段的行为。下面我们就来详细讲解下 Web Components 的生命周期方法、触发时机以及它们的使用场景。

主要生命周期方法

Web Components 的生命周期方法主要包括以下几个:

  1. constructor(): 构造函数,在组件实例化时调用。
  2. connectedCallback(): 当组件被添加到 DOM 中时调用。
  3. disconnectedCallback(): 当组件从 DOM 中移除时调用。
  4. attributeChangedCallback(name, oldValue, newValue): 当组件的属性发生变化时调用。
  5. adoptedCallback(): 当组件被移动到新的文档中时调用。

1. constructor()

触发时机:
构造函数在组件实例化时被调用。它通常用于初始化组件的状态或设置默认值。

使用场景:

class MyComponent extends HTMLElement {constructor() {super();this.attachShadow({ mode: 'open' });}
}
customElements.define('my-component', MyComponent);

这里,constructor() 用于创建一个 shadow DOM,使组件的样式封装在内部,不影响外部样式。

2. connectedCallback()

触发时机:
当组件被添加到 DOM 中时触发。通常用于执行一些与 DOM 相关的初始化工作,比如渲染内容或注册事件监听。

使用场景:

class MyComponent extends HTMLElement {connectedCallback() {this.shadowRoot.innerHTML = `<p>Hello, World!</p>`;}
}
customElements.define('my-component', MyComponent);

在这个例子中,connectedCallback() 被用来向 shadow DOM 插入 HTML 内容。

3. disconnectedCallback()

触发时机:
当组件从 DOM 中移除时触发。它通常用于清理定时器或取消事件监听,以防止内存泄漏。

使用场景:

class MyComponent extends HTMLElement {connectedCallback() {this.timer = setInterval(() => console.log('Tick'), 1000);}disconnectedCallback() {clearInterval(this.timer);}
}
customElements.define('my-component', MyComponent);

在这里,disconnectedCallback() 用于清理定时器,确保在组件移除之后不会继续触发 setInterval

4. attributeChangedCallback(name, oldValue, newValue)

触发时机:
当组件的属性发生变化时触发。可以用来响应属性的变化,并根据新值更新组件的状态或外观。

使用场景:

class MyComponent extends HTMLElement {static get observedAttributes() {return ['data-value'];}attributeChangedCallback(name, oldValue, newValue) {if (name === 'data-value') {console.log(`Attribute changed from ${oldValue} to ${newValue}`);}}
}
customElements.define('my-component', MyComponent);

这里,attributeChangedCallback() 用来响应 data-value 属性的变化。

5. adoptedCallback()

触发时机:
当组件被移动到新的文档时触发(例如通过 document.adoptNode() 方法)。此方法比较少用,但在某些特殊场景下非常有用。

使用场景:

class MyComponent extends HTMLElement {adoptedCallback() {console.log('Component adopted into new document');}
}
customElements.define('my-component', MyComponent);

这在跨文档操作中很有用,比如将组件从一个页面移动到另一个页面。

应用场景

构建一个动态表单组件

假设我们需要构建一个动态表单组件,当用户添加或移除表单字段时,组件可以自动更新。我们可以利用 Web Components 的生命周期方法来实现这一需求。

class DynamicForm extends HTMLElement {constructor() {super();this.attachShadow({ mode: 'open' });this.shadowRoot.innerHTML = `<form id="dynamicForm"><button id="addField">Add Field</button><button id="removeField">Remove Field</button><div id="fields"></div></form>`;}connectedCallback() {this.shadowRoot.getElementById('addField').addEventListener('click', this.addField.bind(this));this.shadowRoot.getElementById('removeField').addEventListener('click', this.removeField.bind(this));}disconnectedCallback() {this.shadowRoot.getElementById('addField').removeEventListener('click', this.addField.bind(this));this.shadowRoot.getElementById('removeField').removeEventListener('click', this.removeField.bind(this));}addField(event) {event.preventDefault();const fieldsContainer = this.shadowRoot.getElementById('fields');const field = document.createElement('input');field.type = 'text';fieldsContainer.appendChild(field);}removeField(event) {event.preventDefault();const fieldsContainer = this.shadowRoot.getElementById('fields');if (fieldsContainer.lastChild) {fieldsContainer.removeChild(fieldsContainer.lastChild);}}
}customElements.define('dynamic-form', DynamicForm);

在这个示例中,我们使用 connectedCallback 方法注册按钮的点击事件来动态添加和删除表单字段,并通过 disconnectedCallback 方法在组件从 DOM 移除时取消事件监听,防止内存泄漏。

响应属性变化的图表组件

假设我们需要一个可以动态更新的图表组件,当数据属性变化时自动重新渲染图表。我们可以利用 attributeChangedCallback 方法来实现。

class DynamicChart extends HTMLElement {static get observedAttributes() {return ['data'];}constructor() {super();this.attachShadow({ mode: 'open' });this.shadowRoot.innerHTML = `<canvas id="chartCanvas"></canvas>`;}connectedCallback() {this.renderChart();}attributeChangedCallback(name, oldValue, newValue) {if (name === 'data' && oldValue !== newValue) {this.renderChart();}}renderChart() {const data = JSON.parse(this.getAttribute('data') || '[]');const ctx = this.shadowRoot.getElementById('chartCanvas').getContext('2d');new Chart(ctx, {type: 'line',data: {labels: data.map(item => item.label),datasets: [{data: data.map(item => item.value),borderColor: 'rgba(75, 192, 192, 1)',borderWidth: 1}]}});}
}customElements.define('dynamic-chart', DynamicChart);

在这个示例中,我们定义了一个观察 data 属性的图表组件,当 data 属性发生变化时,组件会自动重新渲染图表。attributeChangedCallback 方法确保了每次数据更新时,图表都会被重新绘制。

总结

Web Components 提供了一套功能强大的生命周期方法,使开发者可以精细地控制自定义组件的行为和状态。通过正确地使用这些方法,我们可以创建出功能丰富、性能优越且易于维护的 Web 组件。掌握 Web Components 的生命周期方法不仅有助于提升组件的质量和性能,还能显著提高开发效率和代码复用性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/36049.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker安装node部分问题

sudo n latest sudo: n: command not found 如果运行 sudo n latest 时出现&#xff1a; sudo: n: command not found 说明 n 版本管理工具 未安装 或 未添加到 PATH 环境变量。 &#x1f6e0; 解决方案 1️⃣ 先检查 n 是否已安装 运行&#xff1a; which n或者&#xff1…

2025-03-17 NO.1 Quest3 开发环境配置教程

文章目录 准备条件1 Quest3 激活1.1 下载 Oculus 助手1.2 打开 quest 热点1.3 Quest3 连接 wifi1.4 参考教程 2 登录 Oculus&#xff08;*&#xff09;2.1 创建 Meta 账号&#xff08;*&#xff09;2.2 Oculus 软件下载与配置&#xff08;*&#xff09; 3 创建项目3.1 下载 Uni…

简单记一些Kalibr在20.04安装下踩的坑

赠品&#xff1a;官方Kalibr测试数据下载 包括双目&#xff0c;和IMU双目 通过网盘分享的文件&#xff1a;kalibr官方测试数据 链接: https://pan.baidu.com/s/1TgeXuTYLoTrlBbKy5Jf41A?pwdyha6 提取码: yha6 https://github.com/ethz-asl/kalibr/wiki/downloads 先说结论&a…

【C++】:C++11详解 —— 右值引用

目录 左值和右值 左值的概念 右值的概念 左值 vs 右值 左值引用 和 右值引用 左值引用 右值引用 左值引用 vs 右值引用 使用场景 左值引用的使用场景 左值引用的短板 右值引用的使用场景 1. 实现移动语义&#xff08;资源高效转移&#xff09; 2. 优化容器操作&a…

SpringMVC(四)Restful软件架构风格

目录 ​编辑 API接口设计的架构风格 一 Dao层实现&#xff08;处理数据库&#xff09; 二 Sercice层实现&#xff08;处理业务逻辑&#xff09; 三 Controller层&#xff08;处理http请求&#xff09; 四 补充知识点 1 PathVariable - 路径变量 2 CrossOrigin(Origins …

c++图论(二)之图的存储图解

在 C 中实现图的存储时&#xff0c;常用的方法包括 邻接矩阵&#xff08;Adjacency Matrix&#xff09;、邻接表&#xff08;Adjacency List&#xff09; 和 边列表&#xff08;Edge List&#xff09;。以下是具体实现方法、优缺点分析及代码示例&#xff1a; 1. 邻接矩阵&…

ABAP PDF预览

画个屏幕 PDF JPG TXT都可以参考预览&#xff0c;把二进制流传递给标准函数就行 *&---------------------------------------------------------------------* *& Report YDEMO2 *&---------------------------------------------------------------------* *&am…

Compose 的产生和原理

引言 compose 出现的目的&#xff1a; 重新定义android 上ui 的编写方式。为了提高android 原生ui开发效率。让android 的UI开发方式跟上时代。 正文 compose 是什么&#xff1f; 就是一套ui框架 和flutter 一样是一套ui框架 Flutter&#xff1a;跨平台开发趋势与企业应用的…

单口路由器多拨号ADSL实现方法

条件是多拨号场景&#xff0c;公司路由器接口不够用

H3C SecPath SysScan-AK 系列漏洞扫描系统

H3C SecPath SysScan-AK 系列是一款专业的漏洞扫描系统&#xff0c;旨在帮助组织和企业快速、准确地发现网络和系统中存在的安全漏洞。该系统具有以下特点&#xff1a; 1. 多样化的扫描能力&#xff1a;支持对各类网络设备、服务器、应用程序等进行漏洞扫描&#xff0c;能够全面…

[蓝桥杯 2023 省 B] 飞机降落

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间&#xff0c;即它最早可以于 T i T_{i} Ti​ 时刻…

Kafka详解——介绍与部署

1. 什么是 Kafka&#xff1f; Kafka 是一个分布式的消息队列系统&#xff0c;最初由 LinkedIn 开发&#xff0c;后来成为 Apache 开源项目。它的主要用途包括实时数据处理、日志收集、数据流管道构建等。Kafka 具备高吞吐量、可扩展性、持久性和容错性&#xff0c;广泛应用于大…

win10搭建opengl环境搭建并测试--输出立方体球体和碗型并在球体上贴图

参照本文档可以完成环境搭建和测试&#xff0c;如果想要快速完成环境的搭建可以获取本人的工程&#xff0c;包括所用到的工具链和测试工程源码获取&#xff08;非免费介意务下载&#xff09;&#xff1a;链接: https://pan.baidu.com/s/1H2ejbT7kLM9ore5MqyomgA 提取码: 8s1b …

TCP、UDP协议的应用、ServerSocket和Socket、DatagramSocket和DatagramPacket

DAY13.1 Java核心基础 TCP协议 TCP 协议是面向连接的运算层协议&#xff0c;比较复杂&#xff0c;应用程序在使用TCP协议之前必须建立连接&#xff0c;才能传输数据&#xff0c;数据传输完毕之后需要释放连接 就好比现实生活中的打电话&#xff0c;首先确保电话打通了才能进…

如何在 GoLand 中设置默认项目文件夹

在使用 GoLand 进行开发时&#xff0c;设置一个默认的项目文件夹可以大大提高工作效率。默认项目文件夹会在你打开或新建项目时自动预选&#xff0c;避免每次都需要手动导航到目标目录。本文将详细介绍如何在 GoLand 中设置默认项目文件夹。 步骤一&#xff1a;打开系统设置 …

SvelteKit 最新中文文档教程(5)—— 页面选项

前言 Svelte&#xff0c;一个语法简洁、入门容易&#xff0c;面向未来的前端框架。 从 Svelte 诞生之初&#xff0c;就备受开发者的喜爱&#xff0c;根据统计&#xff0c;从 2019 年到 2024 年&#xff0c;连续 6 年一直是开发者最感兴趣的前端框架 No.1&#xff1a; Svelte …

Mac下Ollama安装全攻略:开启本地大模型之旅

文章目录 Mac下Ollama安装全攻略&#xff1a;开启本地大模型之旅一、Ollama 是什么功能特点优势应用场景 二、安装前准备&#xff08;一&#xff09;系统要求&#xff08;二&#xff09;硬件要求 三、下载安装包&#xff08;一&#xff09;官网下载&#xff08;二&#xff09;其…

华为营销流程落地方案:MTC=MTL+LTC

目录 简介 MTC流程 作者简介 简介 只讲最本质的底层逻辑&#xff0c;交付可落地的方案。 作为一个主打实践的产品老炮&#xff0c;接下来我将结合自己的经验&#xff0c; 以华为系的这套流程为基准&#xff0c; 将涉及业务层次的流程全部重构一套本地化、落地化的方案。 …

vscode使用ssh同时连接主机CentOS:user和ubuntu20.04:docker

主机为CentOS docker为Ubuntu20.04 两者可以使用一个vscode远程链接 1.使用已拉取好的Ubuntu镜像建立docker容器 2.进入容器内,下载一些关于ssh的安装包 apt-get install vim apt-get install openssh-client apt-get install openssh-server apt-get install ssh passwd …

NFS网络文件共享服务

文章目录 1. NFS工作原理1.1 挂载结构介绍1.2 NFS的工作原理 2. NFS服务安装2.1 NFS软件列表2.2 启动NFS相关服务2.3 NFS服务常见进程2.4 实战配置NFS服务器端 3. NFS服务配置3.1 在NFS Server端执行的操作3.1.1 查看部署环境3.1.2 启动rpcbind及NFS服务&#xff0c;然后加入开…