Web Components 规范中的 Custom Elements 部分解读与实践

阅读时长 12 分钟读完

前言

在 Web 开发中,我们经常会遇到需要复用的 UI 组件,如弹窗、下拉框等。传统的实现方式是使用模板或框架提供的组件,但是这些组件往往过于笨重,难以满足个性化需求。Web Components 规范的出现,为我们提供了一种更加灵活、轻量的组件开发方式。

Web Components 规范包含四个部分:Custom Elements、Shadow DOM、HTML Templates 和 HTML Imports。本文将重点介绍 Custom Elements 部分的解读与实践。

Custom Elements

Custom Elements 允许开发者创建自定义元素,并且可以通过 JavaScript 来定义它们的行为。这些自定义元素可以像原生 HTML 元素一样使用,并且可以被其他开发者复用。

定义 Custom Elements

定义一个 Custom Element 首先需要继承 HTMLElement 类,然后通过 customElements.define() 方法来注册元素。例如,我们定义一个名为 my-button 的 Custom Element:

-- -------------------- ---- -------
----- -------- ------- ----------- -
  ------------- -
    --------
    ------------------- ----- ------ ---
    ------------------------- - -
      -------
        ------ -
          ----------------- --------
          ------ -----
          ------- -----
          -------------- ----
          -------- --- -----
          ---------- -----
          ------- --------
        -
      --------
      ------------------------------
    --
  -
-

---------------------------------- ----------

在上面的代码中,我们定义了一个名为 MyButton 的类,继承自 HTMLElement 类。在构造函数中,我们首先调用了 super(),然后通过 attachShadow() 方法创建了一个 Shadow DOM,并且设置了 mode 为 open,表示可以从外部访问 Shadow DOM。接着,我们通过 innerHTML 属性设置了 Shadow DOM 的内容,包括了一个样式和一个按钮,按钮中包含了一个 slot,用来接受插入的内容。

最后,我们通过 customElements.define() 方法将 MyButton 类注册为 my-button 元素,这样就可以在 HTML 中使用它了:

生命周期回调

Custom Elements 还提供了一些生命周期回调函数,用于在元素的生命周期中执行一些操作。这些回调函数包括 connectedCallback、disconnectedCallback、attributeChangedCallback 和 adoptedCallback。

  • connectedCallback:当元素被插入到文档中时调用。
  • disconnectedCallback:当元素从文档中移除时调用。
  • attributeChangedCallback:当元素的属性发生变化时调用。
  • adoptedCallback:当元素被移动到新的文档时调用。

例如,我们可以在 connectedCallback 回调函数中添加一个点击事件监听器:

-- -------------------- ---- -------
----- -------- ------- ----------- -
  ------------- -
    --------
    ------------------- ----- ------ ---
    ------------------------- - -
      -------
        ------ -
          ----------------- --------
          ------ -----
          ------- -----
          -------------- ----
          -------- --- -----
          ---------- -----
          ------- --------
        -
      --------
      ------------------------------
    --
  -

  ------------------- -
    ----------------------------------------------------------------- -- -- -
      ------------- -----------
    ---
  -
-

---------------------------------- ----------

属性与属性观察器

Custom Elements 还支持定义属性,并且可以通过属性观察器来监听属性的变化。例如,我们可以给 MyButton 添加一个 disabled 属性,并且在属性变化时修改按钮的 disabled 状态:

-- -------------------- ---- -------
----- -------- ------- ----------- -
  ------ --- -------------------- -
    ------ -------------
  -

  ------------- -
    --------
    ------------------- ----- ------ ---
    ------------------------- - -
      -------
        ------ -
          ----------------- --------
          ------ -----
          ------- -----
          -------------- ----
          -------- --- -----
          ---------- -----
          ------- --------
        -
      --------
      ------------------------------
    --
  -

  --- ---------- -
    ------ ------------------------------
  -

  --- ------------- -
    -- ----- -
      ----------------------------- ----
    - ---- -
      ---------------------------------
    -
  -

  ------------------------------ --------- --------- -
    -- ----- --- ----------- -
      ------------------------------------------------ - --------------
    -
  -
-

---------------------------------- ----------

在上面的代码中,我们通过 static get observedAttributes() 方法定义了一个 observedAttributes 静态属性,用于定义需要观察的属性。接着,我们定义了一个 disabled 属性,通过 get 和 set 方法来获取和设置 disabled 属性的值。在 attributeChangedCallback 回调函数中,我们监听 disabled 属性的变化,并且根据新值修改按钮的 disabled 状态。

实践

下面我们通过一个实例来演示如何使用 Custom Elements 来开发一个复用性高的 UI 组件。

我们先定义一个名为 my-modal 的 Custom Element,用于实现弹窗功能:

-- -------------------- ---- -------
----- ------- ------- ----------- -
  ------ --- -------------------- -
    ------ ------------
  -

  ------------- -
    --------
    ------------------- ----- ------ ---
    ------------------------- - -
      -------
        ----- -
          -------- -----
          --------- ------
          ---- --
          ----- --
          ------ --
          ------- --
          -------- -----
          ----------------- ------- -- -- -----
        -

        ---------------- -
          -------- ------
        -

        ------ -
          --------- ---------
          ---- ----
          ----- ----
          ---------- --------------- ------
          ----------------- -----
          -------------- ----
          -------- -----
        -

        ------- -
          -------- -----
          ---------------- --------------
          ------------ -------
          -------------- -----
        -

        ------ -
          ---------- -----
          ------------ -----
        -

        ------ -
          ------ -----
          ---------- -----
          ------- --------
        -

        -------- -
          -------------- -----
        -

        ------- -
          -------- -----
          ---------------- ---------
        -

        ------- -
          ----------------- --------
          ------ -----
          ------- -----
          -------------- ----
          -------- --- -----
          ---------- -----
          ------- --------
          ------------ ----
        -
      --------
      ---- --------------
        ---- ---------------
          ---- ------------------- --------------------------
          ---- ---------------------
        ------
        ---- --------------------- ----------------------------
        ---- -------------------- ---------------------------
      ------
    --
  -

  --- --------- -
    ------ -----------------------------
  -

  --- ------------ -
    -- ----- -
      ---------------------------- ----
    - ---- -
      --------------------------------
    -
  -

  ------------------------------ --------- --------- -
    -- ----- --- ---------- -
      -- -------------- -
        ---------------------------- - ---------
      - ---- -
        ---------------------------- - ---
      -
    -
  -

  ------------------- -
    ----------------------------------------------------------------- -- -- -
      ------------ - ------
    ---
  -
-

--------------------------------- ---------

在上面的代码中,我们定义了一个名为 MyModal 的类,继承自 HTMLElement 类。在构造函数中,我们通过 innerHTML 属性设置了 Shadow DOM 的内容,包括了一个样式和一个弹窗,弹窗中包含了三个 slot,用来接受插入的标题、内容和底部操作区域。

接着,我们定义了一个 visible 属性,通过 get 和 set 方法来获取和设置 visible 属性的值。在 attributeChangedCallback 回调函数中,我们监听 visible 属性的变化,并且根据新值修改弹窗的显示状态,并且禁止或允许页面滚动。在 connectedCallback 回调函数中,我们添加了一个点击关闭按钮的事件监听器。

接下来,我们可以通过 my-modal 元素来使用这个弹窗组件:

在上面的代码中,我们定义了一个 my-modal 元素,并且通过 slot 插入了标题、内容和底部操作区域。通过设置 visible 属性为 true,可以让弹窗显示出来。

总结

Custom Elements 是 Web Components 规范中非常重要的一部分,它允许开发者创建自定义元素,并且可以通过 JavaScript 来定义它们的行为。Custom Elements 还提供了一些生命周期回调函数、属性和属性观察器等功能,可以帮助我们更加灵活地开发复用性高的 UI 组件。

以上就是本文对 Web Components 规范中的 Custom Elements 部分的解读与实践,希望对大家有所帮助。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/650e631a95b1f8cacd791c5b

纠错
反馈