vue3.2 で追加された defineCustomElement の基本原理の詳細な説明

vue3.2 で追加された defineCustomElement の基本原理の詳細な説明

Webコンポーネント

Web コンポーネントは、再利用可能なカスタム要素 (その機能はコード外部にカプセル化されています) を作成し、Web アプリケーションで使用できるようにするさまざまなテクノロジのセットです。

これは、VueやReactなどのフレームワークを通じてコン​​ポーネント定義を実装する必要がなく、ブラウザのネイティブなコンポーネント定義方法と同等です。

カスタム要素

概要

customElements は、Window オブジェクトの読み取り専用プロパティです。このインターフェイスは、CustomElementRegistry オブジェクトへの参照を返します。このオブジェクトは、新しいカスタム要素を登録したり、以前に定義されたカスタム要素に関する情報を取得したりするために使用できます。

HTMLTemplateElement コンテンツ テンプレート要素

概要

HTML <template> 要素は、ページの読み込み時にはレンダリングされないが、実行時に JavaScript を使用してインスタンス化される可能性のあるクライアント側コンテンツを保持するためのメカニズムです。
テンプレートは、後で使用するためにドキュメントに保存できるコンテンツの一部と考えてください。パーサーはページを読み込むときに <template> 要素のコンテンツを処理しますが、そのコンテンツが有効であることを確認するためだけに処理し、要素のコンテンツはレンダリングされません。

共通プロパティ

content DocumentFragment 要素フラグメントのコンテンツを取得します。これは、document.createDocumentFragment() によって作成された要素フラグメントと同等です。

  <!-- テンプレートフラグメントを定義します -->
  <テンプレートid="要素テンプレート">
    <div>テストテンプレート</div>
  </テンプレート>

  <スクリプト>
    /* テンプレートフラグメントを取得します */
    const ele = document.getElementById('要素テンプレート')
    ele.content インスタンス DocumentFragment //true

    /* createDocumentFragment で HTML フラグメントを作成する*/
    定数div = document.createDocumentFragment('div')
    div インスタンス DocumentFragment //true

    /* 結論は*/
    // HTML で定義されたテンプレートは、createDocumentFragment によって作成された HTML フラグメントと同等のコンテンツを取得します</script>

シャドウルート

概要

Shadow DOM API の ShadowRoot インターフェースは、ドキュメントのメイン DOM ツリーとは別にレンダリングされる DOM サブツリーのルート ノードです。
モードを open に設定して Element.attachShadow() で作成されたと仮定すると、Element.shadowRoot プロパティを使用して要素への参照を取得できます。

Element.attachShadow() 経由でシャドウ DOM をマウントします。

完全なデモコード

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
  <title>ドキュメント</title>
</head>
<本文>

  <テストシャドウルート><​​/テストシャドウルート>

  <テンプレートid="templateEle">
    <スタイル>
      。主要{
        色: #f00;
      }
    </スタイル>
    <div class="main">
      私はテンプレートフラグメントです<!-- スロットの使用 -->
      <スロット名="ヘッダー"></スロット>
    </div>
  </テンプレート>
  <テストテンプレート要素>
    <!-- スロットを定義する -->
    <スタイル>
      。スロット{
        色: rgb(87, 28, 223);
      }
    </スタイル>
    <div class="slot" slot="header">私はスロットです</div>
  </テストテンプレート要素>

  <!-- ライフサイクルテスト -->
  <div id="moveDiv">
    <button id="add">追加</button>
    <button id="update">更新</button>
    <button id="move">移動</button>
    <button id="remove">削除</button>
  </div>

  <!-- マウントは -->
  <div is="test-is-com">
    <div>AAA</div>
  </div>


  <スクリプト>
    /* カスタム Web コンポーネント */
    customElements.define('test-shadow-root', クラスはHTMLElementを拡張します {
      /* test-shadow-root コンポーネントが DOM にマウントされたら、コンストラクタを実行します */
      コンストラクタ() {
        素晴らしい()
        const shadowRoot = this.attachShadow({mode: 'open'}) //指定された要素にシャドウDOMをアタッチします
        // this.attachShadow() メソッドが実行されると、shadowRoot がコンストラクターにマウントされ、これを介してアクセスできるようになります // モード open のシャドウ ルート要素は、js の外部からルート ノードにアクセスできます // モード closed は、js の外部からのクローズ シャドウ ルート ノードへのアクセスを拒否します // console.log('execution', this)
        定数div = document.createElement('div')
        div.textContent = '私はdivのコンテンツです'
        // shadowRoot.appendChild()
        // console.log('this', this.shadowRoot)
        shadowRoot.appendChild(div)
        // this.shadowRoot === shadowRoot は true
      }
    })

    /* テンプレートを通じて HTMLTemplateElement をカスタマイズする */
    customElements.define('test-template-ele', クラスは HTMLElement を拡張します {
      コンストラクタ() {
        素晴らしい()
        const temEle = document.querySelector('#temEle')
        const templateContent = temEle.content // HTML フラグメントを取得します // console.log('AA', templateContent instanceof DocumentFragment) //true
        // テンプレートコンテンツ
        // テンプレートフラグメントをマウントするためのシャドウDOMを作成する const shadowRoot = this.attachShadow({mode: 'open'})
        // コンソールログ('shadowRoot', shadowRoot)
        shadowRoot.appendChild(テンプレートコンテンツ)
      }
    })

    /* js を通じて Web コンポーネントを作成し、ライフサイクル関数をテストします */
      クラスLifeCycleはHTMLElementを拡張します。
        static get observedAttributes() { // attributeChangedCallback をトリガーするには、コンポーネントに属性を追加する必要があります
          ['c', 'l'] を返します。
        }

        コンストラクタ() {
          素晴らしい()
          const shadowRoot = this.attachShadow({mode: 'open'})
          const div = `<div>
            <header>私の頭</header>
            <div>コンテンツ</div>
            <footer>テール</footer>
          </div>`
          shadowRoot.innerHTML = div
        }

        connectedCallback() { //追加するときはconsole.log('add')を実行します
        }
        disconnectedCallback() //削除する場合はconsole.log('disconnectedCallback')を実行
        }
        採用されたコールバック() {
          console.log('採用されたコールバック')
        }
        attributeChangedCallback() { //属性が変更されると、console.log('attributeChangedCallback')
        }
      }

      customElements.define('テストライフサイクル', ライフサイクル)

      定数 add = document.querySelector('#add')
      定数更新 = document.querySelector('#update')
      const 移動 = document.querySelector('#move')
      定数remove = document.querySelector('#remove')
      const moveDiv = document.querySelector('#moveDiv')
      testLifeDom = null とします

      関数ランダム(最小値, 最大値) {
        Math.floor(Math.random() * (max - min + 1) + min) を返します。
      }

      add.addEventListener('クリック', () => {
        testLifeDom = document.createElement('test-life-cycle') //上記で定義したカスタムコンポーネントを作成します // ​​console.log('testLifeDom', testLifeDom)
        document.body.appendChild(testLifeDom);
        testLifeDom.setAttribute('l', '100');
        testLifeDom.setAttribute('c', 'red');
        コンソールログ('add'、testLifeDom)
      })

      更新.addEventListener('クリック', () => {
        const div = '<div>更新されました</div>'
        // console.log('update', testLifeDom.shadowRoot.innerHTML)
        testLifeDom.shadowRoot.innerHTML = div
        testLifeDom.setAttribute('l', ランダム(50, 200));
        testLifeDom.setAttribute('c', `rgb(${random(0, 255)}, ${random(0, 255)}, ${random(0, 255)})`);
      })

      move.addEventListener('クリック', () => {
        コンソールログ('moveDiv', moveDiv)
        移動Div.appendChild(testLifeDom)
      })

      削除.addEventListener('クリック', () => {
        コンソールログ('削除')
        document.body.removeChild(testLifeDom);
      })

      /* is 経由でコンポーネントをマウントする*/

      customElements.define('test-is-com', クラスは HTMLDivElement を拡張します {
        コンストラクタ() {
          素晴らしい()
          console.log('マウント', this.innerHTML)
          // マウントにより、これは現在マウントされている要素インスタンスになります。この方法で、いくつかの操作を実装できます。}
      }, {extends: 'div'})

  </スクリプト>
</本文>
</html>

これで、vue3.2 で追加された defineCustomElement の基本原理に関するこの記事は終了です。vue3.2 の defineCustomElement に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • レスポンシブ原則をシミュレートするための基礎コードの Vue 実装の例
  • Vueデータ双方向バインディングの基本的な実装原則
  • Vue の基本的な実装原則の概要
  • Vue の基本原理についてどれくらい知っていますか?

<<:  テーブルを作成するための MySQL SQL ステートメントの詳細な概要

>>:  CentOS7でXShellとネットワーク設定を接続する方法

推薦する

MySQL でデータの重複挿入を回避する 4 つの方法

最も一般的な方法は、フィールドに主キーまたは一意のインデックスを設定することです。重複データを挿入す...

ローカルの Windows リモート デスクトップから Alibaba Cloud Ubuntu 16.04 サーバーに接続する方法

ローカル Windows リモート デスクトップが Alibaba Cloud Ubuntu 16....

docker を使用した pxc クラスターのインストールに関する詳細なチュートリアル

目次序文事前準備ディレクトリを作成するcustom.cnf を作成する証明書を作成するpxc クラス...

css3 flexレイアウト justify-content:space-between 最後の行は左揃えになります

justify-content:space-betweenレイアウトを使用する場合、要素の最後の行に...

HTMLでのフォーム送信の実装

フォーム送信コード1. ソースコード分析 <!DOCTYPE html> <htm...

Dockerカスタムブリッジdocker0とdockerのコマンド操作の開始、終了、再起動

質問会社がサーバーを移行した後、デフォルトで作成された docker0 ブリッジが会社の外部ネットワ...

Linuxフラッシュのインストール方法

Linuxにフラッシュをインストールする方法1. Flashの公式サイトにアクセスし、ダウンロードを...

CentOSバージョンにDockerをインストールする際のエラーの解決方法

1. バージョン情報 # cat /etc/system-release CentOS Linux ...

ウェブデザインの教育または学習プログラム

セクションコース内容営業時間1 ウェブデザインの概要2 2 HTML 基本タグとフォーマットタグ 2...

Rx レスポンシブプログラミングについての簡単な説明

目次1. 観察可能2. 高階関数3. エクスプレスボックスモデル3.1. エクスプレスボックスモデル...

Vue 折りたたみ表示の複数行テキスト コンポーネントの実装コード

折りたたみ表示の複数行テキストコンポーネント複数行のテキスト コンポーネントを折りたたんで表示し、展...

JavaScript における Arguments オブジェクトの使用に関する詳細な説明

目次序文議論の基本概念議論の役割実パラメータと仮パラメータの数を取得する実際のパラメータ値を変更する...

派手なカルーセル効果を実現するJavaScript

この記事では、JavaScriptで派手なカルーセル効果を実装する2つの方法を紹介します。具体的な内...

デザイン理論: テキストの読みやすさと可読性

<br />少し前に、ビジネス上の必要性から、ラップトップに Souba をインストール...

Docker で Spring-boot プロジェクトをデプロイするためのサンプル コード

1. 基本的な Spring-boot クイックスタート1.1 クイックスタート pom.xml は...