Web Componentメモ

16169 ワード

前言


フロントエンドのコンポーネント化はJSフレームワークに基づいて行われなくてもいいですか?本質的には、JSは完全に行うことができ、本当にフロントエンドのコンポーネント化を阻害しているのは、他の2人の子供、CSSとDOMです.

web component


WebComponentが提供する解決策は、DOM、CSSOM、JavaScriptをローカル環境で実行できるように、ローカルビューのパッケージング能力を提供することであり、ローカルのCSSとDOMがグローバルに影響を与えないようにすることである.カスタム要素、shadow DOM、HTMLテンプレートなど、テクノロジーの組み合わせです.コードを分析してみましょう.

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Documenttitle>
  head>
  <body>
    <template id="headers">
      <style>
        div {
          background: #3e3;
          width: 300px;
          height: 300px;
          box-shadow: antiquewhite 10px 10px;
          color: red;
          margin: 0 auto;
          font-size: 56px;
        }
      style>
      <script>
        function foo() {
          console.log("green foo");
        }
      script>
      <div>
        this is a green div
      div>
    template>
    <script>
      class ShadowDOM extends HTMLElement {
        constructor() {
          super();
          const content = document.querySelector("#headers").content;
          const shadow = this.attachShadow({ mode: "open" });
          shadow.appendChild(content.cloneNode(true));
        }
      }
      customElements.define("header-component", ShadowDOM);
    script>
    <header-component>header-component>
    <div>this is a web componentdiv>
  body>
html>

分析すると、このコードは実は全部で3つのことをしました.それぞれshadowを構築し、shadowをマウントし、shadowを展示します.
まず構築:
    <template id="headers">
      <style>
        div {
          background: #3e3;
          width: 300px;
          height: 300px;
          box-shadow: antiquewhite 10px 10px;
          color: red;
          margin: 0 auto;
          font-size: 56px;
        }
      style>
      <script>
        function foo() {
          console.log("green foo");
        }
      script>
      <div>
        this is a green div
      div>
    template>

templateを使って小包をして、他のラベルと同じように、中にはstyle、script、htmlラベルが書いてもいいので、この部分は理解しやすいです.
セグメント2:
    <script>
      class ShadowDOM extends HTMLElement {
        constructor() {
          super();
          const content = document.querySelector("#headers").content;
          const shadow = this.attachShadow({ mode: "open" });
          shadow.appendChild(content.cloneNode(true));
        }
      }
      customElements.define("header-component", ShadowDOM);
    </script>

すなわち、ここではshaowDOMクラスを定義してHTML Elementを継承し、templateのcontentを取得し、attachShadowメソッドを使用してshadowの構築を支援し、shadowにcontentを追加するだけでよい.
最後にこのcomponentを定義するだけでいいdefineの最初のパラメータはcomponentの名前で、2番目はshadowDOMです.
3段目は、Vue、Reactと同様にそのまま使えばよい.
しかし、shadowDOMはDOMとCSSを遮断することができますが、JSを遮断することはできません.私たちはホームページでfoo関数を直接調整し、正常に呼び出すことができます.この部分の原因は多分JSのコンポーネント化が十分にできているので、蛇足を描く必要はありません.

原理の簡単な分析


レイアウトツリーを作成すると、レンダリングエンジンはheaders属性の下のshadow-root要素がshadowDOMであるかどうかを判断し、もしそうであれば、shadowDOM内部要素のノードでCSSスタイルを選択すると、直接shadowDOM内部のCSS属性を適用し、最終的にレンダリングされる効果は影