使用 Web Components 实现数据双向绑定的方式

阅读时长 8 分钟读完

Web Components 是一种为了提高 Web 应用开发的可复用性和可维护性而推出的技术,它包括了四个核心概念,分别是自定义元素、影子 DOM、HTML 模板和 HTML Imports。其中,自定义元素是指允许开发者定义自己的 HTML 元素,以及为它们添加自定义行为和属性的能力。在本篇文章中,我们将介绍如何利用 Web Components 的自定义元素功能,实现数据双向绑定的方式。

Web Components 的自定义元素

Web Components 的自定义元素,允许开发者通过继承现有 Web 元素类(例如 HTMLButtonElement、HTMLInputElement 等等)或者继承 HTMLElement 或其子类来创建自定义元素,自定义元素的名称以及元素的行为和样式可由开发者完全控制。除此之外,自定义元素也支持自定义属性,可以利用这些属性来实现数据双向绑定。

下面是一个最简单的自定义元素的示例代码,该自定义元素是一个灰色的矩形:

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

在上述代码中,我们通过 class Rectangle extends HTMLElement 定义了一个自定义元素类,并在类的 connectedCallback() 方法中定义了该自定义元素的样式。最后通过 customElements.define('my-rectangle', Rectangle) 方法将该自定义元素注册到浏览器中。

数据双向绑定的实现

实现数据双向绑定可以采用两种方式,分别是侦听属性变化和侦听元素事件。

侦听属性变化

我们可以为自定义元素添加一个自定义属性,当属性值发生变化时,触发一个 customAttributeChangedCallback() 回调函数,该函数中可通过 this.getAttribute('属性名称') 获取新的属性值,并将其赋给自定义元素的某个 DOM 元素或属性,以此来实现数据双向绑定。

下面是一个示例代码,其中 my-input 是一个包含输入框的自定义元素,它的 value 自定义属性用于存储输入框中的文本内容,当 value 属性的值发生变化时,会自动更新输入框中的文本内容。

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

在上述代码中,我们通过 static get observedAttributes() { return ['value']; } 定义了我们要侦听的自定义属性名为 value。在自定义元素的构造函数中,我们创建了一个包含输入框的 shadow DOM,并在输入框的 input 事件监听器中,更新 value 自定义属性的值。当 value 自定义属性的值发生变化时,attributeChangedCallback() 回调函数会自动调用,该函数中我们先判断新旧两个属性值是否相同,如果不同,则将新的 value 值赋给输入框的 value 属性。

对于上述代码,可以考虑进一步封装成通用的数据双向绑定组件(例如 data-binding-input),并且通过 slot 的方式,使其具有更高的灵活性。

侦听元素事件

除了侦听自定义属性变化外,我们也可以通过侦听自定义元素内的 DOM 元素事件来实现数据双向绑定。这种方式相对于侦听自定义属性变化的方式,更加灵活,尤其是针对非表单元素的数据绑定。

下面是一个示例代码,其中 my-counter 是一个包含计数器的自定义元素,它采用了侦听 my-counter 内的 DOM 元素 button 上的 click 事件,实现了数据双向绑定。

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

在上述代码中,我们通过 this.dispatchEvent(new CustomEvent('change', { detail: value })) 触发了 my-counter 自定义元素上的 change 事件,并且在 HTML 上通过 on-change 属性将 change 事件绑定到一个函数中,以便在事件触发时获取最新的数值。

总结

使用 Web Components 实现数据双向绑定,是一种方便、灵活、可维护的方式。我们可以根据需求,选择不同的数据绑定方式(侦听属性变化或者侦听元素事件),灵活运用自定义元素和 Shadow DOM 技术,实现更加优雅和高效的 Web 应用。

参考资料

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

纠错
反馈