Redian新闻
>
开发你的第一个 Web 组件 | Linux 中国

开发你的第一个 Web 组件 | Linux 中国

科技
 
导读:不要做重复的工作;基于浏览器开发 Web App 时,需要制作一些可重用的模块。             
本文字数:4631,阅读时长大约:6分钟

Web 组件是一系列开源技术(例如 JavaScript 和 HTML)的集合,你可以用它们创建一些 Web App 中可重用的自定义元素。你创建的组件是独立于其他代码的,所以这些组件可以方便地在多个项目中重用。

首先,它是一个平台标准,所有主流的浏览器都支持它。

Web 组件中包含什么?

◈ 定制元素:JavaScript API 支持定义 HTML 元素的新类别。
◈ 影子 DOM:JavaScript API 提供了一种将一个隐藏的、独立的 文档对象模型🔗 en.wikipedia.org(DOM)附加到一个元素的方法。它通过保留从页面的其他代码分离出来的样式、标记结构和行为特征对 Web 组件进行了封装。它会确保 Web 组件内样式不会被外部样式覆盖,反之亦然,Web 组件内样式也不会“泄露”到页面的其他部分。
◈ HTML 模板:该元素支持定义可重用的 DOM 元素。可重用 DOM 元素和它的内容不会呈现在 DOM 内,但仍然可以通过 JavaScript 被引用。

开发你的第一个 Web 组件

你可以借助你最喜欢的文本编辑器和 JavaScript 写一个简单的 Web 组件。本指南使用 Bootstrap 生成简单的样式,并创建一个简易的卡片式的 Web 组件,给定了位置信息,该组件就能显示该位置的温度。该组件使用了 Open Weather API🔗 openweathermap.org,你需要先注册,然后创建 APPID/APIKey,才能正常使用。

调用该组件,需要给出位置的经度和纬度:

  1. <weather-card longitude='85.8245' latitude='20.296' />

创建一个名为 weather-card.js 的文件,这个文件包含 Web 组件的所有代码。首先,需要定义你的组件,创建一个模板元素,并在其中加入一些简单的 HTML 标签:

  1. const template = document.createElement('template');
  2. template.innerHTML = `
  3.   <div class="card">
  4.     <div class="card-body"></div>
  5.   </div>
  6. `

定义 Web 组件的类及其构造函数:

  1. class WeatherCard extends HTMLElement {
  2.   constructor() {
  3.     super();
  4.     this._shadowRoot = this.attachShadow({ 'mode': 'open' });
  5.     this._shadowRoot.appendChild(template.content.cloneNode(true));
  6.   }
  7.   ......
  8. }

构造函数中,附加了 shadowRoot 属性,并将它设置为开启模式。然后这个模板就包含了 shadowRoot 属性。

接着,编写获取属性的函数。对于经度和纬度,你需要向 Open Weather API 发送 GET 请求。这些功能需要在 connectedCallback 函数中完成。你可以使用 getAttribute 方法访问相应的属性,或定义读取属性的方法,把它们绑定到本对象中。

  1. get longitude() {
  2.   return this.getAttribute('longitude');
  3. }
  4. get latitude() {
  5.   return this.getAttribute('latitude');
  6. }

现在定义 connectedCallBack 方法,它的功能是在需要时获取天气数据:

  1. connectedCallback() {
  2. var xmlHttp = new XMLHttpRequest();
  3. const url = `http://api.openweathermap.org/data/2.5/weather?lat=${this.latitude}&lon=${this.longitude}&appid=API_KEY`
  4. xmlHttp.open("GET", url, false);
  5. xmlHttp.send(null);
  6. this.$card = this._shadowRoot.querySelector('.card-body');
  7. let responseObj = JSON.parse(xmlHttp.responseText);
  8. let $townName = document.createElement('p');
  9. $townName.innerHTML = `Town: ${responseObj.name}`;
  10. this._shadowRoot.appendChild($townName);
  11. let $temperature = document.createElement('p');
  12. $temperature.innerHTML = `${parseInt(responseObj.main.temp - 273)} &deg;C`
  13. this._shadowRoot.appendChild($temperature);
  14. }

一旦获取到天气数据,附加的 HTML 元素就添加进了模板。至此,完成了类的定义。

最后,使用 window.customElements.define 方法定义并注册一个新的自定义元素:

  1. window.customElements.define('weather-card', WeatherCard);

其中,第一个参数是自定义元素的名称,第二个参数是所定义的类。这里是 整个组件代码的链接🔗 gist.github.com

你的第一个 Web 组件的代码已完成!现在应该把它放入 DOM。为了把它放入 DOM,你需要在 HTML 文件(index.html)中载入指向 Web 组件的 JavaScript 脚本。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.   <meta charset="UTF-8">
  5. </head>
  6. <body>
  7. <weather-card longitude='85.8245' latitude='20.296'/>
  8.   <script src='./weather-card.js'></script>
  9. </body>
  10. </html>

这就是显示在浏览器中的 Web 组件:

Web component displayed in a browser

由于 Web 组件中只包含 HTML、CSS 和 JavaScript,它们本来就是浏览器所支持的,并且可以无瑕疵地跟前端框架(例如 React 和 Vue)一同使用。下面这段简单的代码展现的是它跟一个由 Create React App🔗 create-react-app.dev 引导的一个简单的 React App 的整合方法。如果你需要,可以引入前面定义的 weather-card.js,把它作为一个组件使用:

  1. import './App.css';
  2. import './weather-card';
  3. function App() {
  4.   return (
  5.   <weather-card longitude='85.8245' latitude='20.296'></weather-card>
  6.   );
  7. }
  8. export default App;

Web 组件的生命周期

一切组件都遵循从初始化到移除的生命周期法则。每个生命周期事件都有相应的方法,你可以借助这些方法令组件更好地工作。Web 组件的生命周期事件包括:

◈ Constructor:Web 组件的构造函数在它被挂载前调用,意味着在元素附加到文档对象前被创建。它用于初始化本地状态、绑定事件处理器以及创建影子 DOM。在构造函数中,必须调用 super(),执行父类的构造函数。
◈ ConnectedCallBack:当一个元素被挂载(即,插入 DOM 树)时调用。该函数处理创建 DOM 节点的初始化过程中的相关事宜,大多数情况下用于类似于网络请求的操作。React 开发者可以将它与 componentDidMount 相关联。
◈ attributeChangedCallback:这个方法接收三个参数:nameoldValue 和 newValue。组件的任一属性发生变化,就会执行这个方法。属性由静态 observedAttributes 方法声明:
  1. static get observedAttributes() {
  2.   return ['name', '_id'];
  3. }
一旦属性名或 _id 改变,就会调用 attributeChangedCallback 方法。
◈ DisconnectedCallBack:当一个元素从 DOM 树移除,会执行这个方法。它相当于 React 中的 componentWillUnmount。它可以用于释放不能由垃圾回收机制自动清除的资源,比如 DOM 事件的取消订阅、停用计时器或取消所有已注册的回调方法。
◈ AdoptedCallback:每次自定义元素移动到一个新文档时调用。只有在处理 IFrame 时会发生这种情况。

模块化开源

Web 组件对于开发 Web App 很有用。无论你是熟练使用 JavaScript 的老手,还是初学者,无论你的目标客户使用哪种浏览器,借助这种开源标准创建可重用的代码都是一件可以轻松完成的事。

插图:Ramakrishna Pattnaik,CC BY-SA 4.0🔗 creativecommons.org


via: https://opensource.com/article/21/7/web-components

作者:Ramakrishna Pattnaik 选题:lujun9972 译者:cool-summer-021 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出


LCTT 译者 :cool-summer-021
🌟🌟
翻译: 3.0 篇
|
贡献: 21 天
2022-09-22
2022-10-13
https://linux.cn/lctt/cool-summer-021
欢迎遵照 CC-BY-SA 协议规定转载,
如需转载,请在文章下留言 “转载:公众号名称”,
我们将为您添加白名单,授权“转载文章时可以修改”。

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
桌面 Linux 市场份额(2022 年 7 月) | Linux 中国图解如何升级到 Linux Mint 21 | Linux 中国《邪不压正》原作《侠隐》作者张北海走了。。。。Linux 优先的 AI 图像提升器 Upscayl 发布了第一个版本 | Linux 中国5 个 htop 替代:增强你的 Linux 系统监控体验 | Linux 中国准备好在 Debian Linux 上获得 Ubuntu MATE 的体验吧! | Linux 中国在 Linux 上截屏的 3 种方法 | Linux 中国如何在 Linux 中实时监控日志文件(桌面和服务器) | Linux 中国用惯 Linux 的人第一次用 Windows 或 macOS 会怎样? | Linux 中国在 Linux 中使用 Etcher 创建可启动 USB – 下载和使用指南 | Linux 中国一个适用于苹果芯片的原生 Linux GPU 驱动程序几乎就绪! | Linux 中国关于 Linux 和 Git 的创造者 Linus Torvalds 的 20 件趣事 | Linux 中国5 款适用于 Linux 的笔记应用 | Linux 中国Fedora Linux 的各种版本 | Linux 中国在美国203.怕中国人,展厨艺,去佛州我在Linux开发板上跑的第一个Qt程序“作弊”:只需要知道这一个 Linux 命令就够了 | Linux 中国Rosalía 登意大利版《VOGUE》封面!是《当你老了》,而不是我......!在你的 Linux 终端中玩经典的贪吃蛇游戏 | Linux 中国Kali Linux 发布今年最后一个版本 | Linux 中国Tuxedo 已对所有用户开放基于 Ubuntu 的 TUXEDO OS | Linux 中国如何在 Linux 中找到一个进程 ID 并杀死它 | Linux 中国微软决定放弃 Teams 的 Linux 应用,而用渐进式网页应用取代 | Linux 中国如何在 Linux 中更改 GRUB 主题 | Linux 中国你应该知道的 22 个基本的 Linux 网络命令 | Linux 中国3 个可在 Linux 上玩旧 NES 游戏的 NES 模拟器 | Linux 中国10 大可以摧毁你的 Linux 的命令 | Linux 中国波士顿击剑课程全新上线!激发你的骑士精神!Atoms 是一个可以让你轻松管理 Linux Chroot 环境的 GUI 工具 | Linux 中国戏说“贫贱不能移”----(图)7 个基于 Fedora Linux 的最佳发行版 | Linux 中国在 Manjaro 和其他基于 Arch Linux 的发行版上安装 Spotify | Linux 中国我是如何看中华民族和华夏文明的?Blackbox:极简主义 Linux 用户的美观终端 | Linux 中国
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。