编写你的第一个 Web 组件

不要重复你自己;创建可在任何浏览器中编写 Web 应用程序时重复使用的元素。
62 位读者喜欢这篇文章。
Digital creative of a browser on the internet

Web 组件是开放源代码技术的集合,例如 JavaScript 和 HTML,使你可以创建自定义元素,你可以在 Web 应用程序中使用和重用这些元素。你创建的组件独立于代码的其余部分,因此它们易于在许多项目中重用。

最重要的是,它是一个受所有主要现代浏览器支持的平台标准。

Web 组件包含什么?

  • 自定义元素: 此 JavaScript API 允许你定义新的 HTML 元素类型。
  • Shadow DOM: 此 JavaScript API 提供了一种将隐藏的独立 文档对象模型 (DOM) 附加到元素的方法。这通过使样式、标记结构和行为与页面上的其他代码隔离来封装你的 Web 组件。它可以确保样式不会被外部样式覆盖,或者相反,Web 组件的样式不会“泄漏”到页面的其余部分
  • HTML 模板: 元素允许你定义可重复使用的 DOM 元素。该元素及其内容不会在 DOM 中呈现,但仍然可以使用 JavaScript 引用。

编写你的第一个 Web 组件

你可以使用你喜欢的文本编辑器和 JavaScript 编写一个简单的 Web 组件。本操作指南使用 bootstrap 生成简单的样式,然后创建一个简单的卡片 Web 组件来显示作为属性传递给它的位置的温度。该组件使用 Open Weather API,它要求你通过登录来生成 APPID/APIKey。

调用此 Web 组件的语法需要位置的经度和纬度

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

创建一个名为 weather-card.js 的文件,其中将包含 Web 组件的所有代码。首先定义你的组件。这可以通过创建模板元素并在其中添加一些简单的 HTML 元素来完成

const template = document.createElement('template');

template.innerHTML = `
  <div class="card">
    <div class="card-body"></div>
  </div>
`

开始定义 WebComponent 类及其构造函数

class WeatherCard extends HTMLElement {
  constructor() {
    super();
    this._shadowRoot = this.attachShadow({ 'mode': 'open' });
    this._shadowRoot.appendChild(template.content.cloneNode(true));
  }
  ….
}

构造函数附加 shadowRoot 并将其设置为开放模式。然后将模板克隆到 shadowRoot。

接下来,访问属性。这些是经度和纬度,你需要它们来向 Open Weather API 发出 GET 请求。这需要在 connectedCallback 函数中完成。你可以使用 getAttribute 方法来访问属性,或者定义 getter 将它们绑定到此对象

get longitude() {
  return this.getAttribute('longitude');
}

get latitude() {
  return this.getAttribute('latitude');
}

现在定义 connectedCallBack 方法,该方法在每次挂载时获取天气数据

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

检索到天气数据后,将其他 HTML 元素添加到模板中。现在,你的类已定义。

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

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

第一个参数是自定义元素的名称,第二个参数是定义的类。这是一个 指向整个组件的链接

你已经编写了你的第一个 Web 组件!现在是时候将其带到 DOM 了。为此,你必须在 HTML 文件(将其命名为 index.html)中加载包含 Web 组件定义的 JavaScript 文件

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
</head>

<body>
  <weather-card longitude='85.8245' latitude='20.296'></weather-card>
  <script src='./weather-card.js'></script>
</body>

</html>

这是浏览器中的 Web 组件

因为 Web 组件只需要 HTML、CSS 和 JavaScript,所以它们受到浏览器原生支持,并且可以与前端框架(包括 React 和 Vue)无缝使用。以下简单代码段显示了如何在带有 Create React App 引导的简单 React 应用程序中使用 Web 组件。为此,你需要导入你之前定义的 weather-card.js 文件并将其用作组件

import './App.css';
import './weather-card';

function App() {
  return (
  <weather-card longitude='85.8245' latitude='20.296'></weather-card>
  );
}

export default App;

Web 组件的生命周期

所有组件都遵循从初始化到从 DOM 中移除(即,卸载)的生命周期。方法与每个生命周期事件相关联,以便你可以更好地控制组件。Web 组件的各种生命周期事件包括

  • 构造函数: Web 组件的构造函数在其挂载之前调用,这意味着它是在元素附加到文档之前创建的。它用于初始化本地状态、绑定事件处理程序和创建 shadow DOM。构造函数必须调用 super() 来调用 Web 组件类扩展的类。
  • ConnectedCallBack: 当元素被挂载(即插入到 DOM 树中)时调用此方法。它处理初始化创建 DOM 节点,并且主要用于实例化网络请求等操作。React 开发人员可以将其与 componentDidMount 相关联。
  • attributeChangedCallback: 此方法接受三个参数:nameoldValuenewValue。每当组件的观察属性之一发生更改时,都会调用它。使用静态 observedAttributes getter 将属性声明为观察属性
    static get observedAttributes() {
      return ['name', '_id'];
    }

    每当属性 name 或 _id 发生更改时,都会调用 attributeChangedCallback

  • DisconnectedCallBack: 当元素从 DOM 树中移除(即卸载)时调用此方法。它等同于 React 的 componentWillUnmount。它用于释放不会自动进行垃圾回收的资源,例如取消订阅 DOM 事件、停止间隔计时器或取消注册所有已注册的回调。
  • AdoptedCallback: 每次自定义元素移动到新文档时都会调用它。它仅在处理 IFrames 时发生。

模块化开源

Web 组件可能是开发 Web 应用程序的强大方法。无论你是熟悉 JavaScript 还是刚开始使用它,都可以使用这种出色的开放标准轻松创建可重用的代码,无论你的目标受众使用哪种浏览器。

接下来阅读什么
Ramakrishna Pattnaik
Ramakrishna Pattnaik 是一位来自 Bhubaneswar 的 Web 开发人员,目前在班加罗尔的 Red Hat Middleware 团队担任副软件工程师。一位开源爱好者和贡献者。热爱小说。

评论已关闭。

Creative Commons License本作品采用 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.