解决 Custom Elements 遇到的元素生命周期问题

Custom Elements 是一项 Web Components API,允许开发者创建自定义 HTML 元素,这些元素可以完全贴合业务逻辑从而增强页面的功能。然而,在使用 Custom Elements 的过程中,我们可能会遇到一些元素生命周期上的问题,本文将会讨论如何解决这些问题。

问题一:Custom Element 的生命周期

Custom Elements 有以下生命周期:

  • connectedCallback
  • disconnectedCallback
  • adoptedCallback

分别在元素被插入到页面 DOM、从页面 DOM 中删除、从一个文档移到另一个文档时执行。这些 callback 与 HTML 元素的生命周期类似,但 Custom Element 的生命周期更为复杂,因为 Custom Element 让开发者可以完全掌控自定义元素的生命周期。

问题二:setState() 不会触发 Custom Element 的重新渲染

在使用 Custom Elements 的过程中,我们可能需要将一些变量储存到元素中,并且希望当这些变量改变时能够重新渲染 Custom Element。这时候我们可以使用 setState(),例如:

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

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

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

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

然而,这份代码有一个问题:当 MyComponent 中的 setState() 被调用时,render() 并不会被触发,因此 Custom Element 不会得到更新。造成这个问题的原因是,Object.assign() 并不会触发 Custom Element 的 re-render,因此我们需要寻找一个合适的办法来解决这个问题。

解决方案

我们可以使用 MutationEvent 和 MutationObserver 来监听 Custom Element 的变化,这样当元素的状态改变时我们可以手动触发一个独立的 callback 来重新渲染 Custom Element。

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

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

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

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

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

现在我们在 setState() 中通过 dispatchEvent()来派发一个事件通知 Custom Element 的状态已经改变,然后在 connectedCallback() 中使用 MutationObserver 监听这个事件,并触发一个重新渲染。

结论

Custom Elements 的复杂生命周期使得开发者可以完全掌控自定义元素的生命周期,但同时也增加了开发过程中的复杂性。通过手动触发重新渲染的方式,我们可以解决 setState() 不会触发 Custom Element 的重新渲染的问题。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/67202c5b2e7021665e0105fa