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とネットワーク設定を接続する方法

推薦する

Uniapp は DingTalk スキャンコード ログイン サンプル コードを実装します

UniappにはDingTalk認証ログインがないため、この記事ではDingTalk QRコードログ...

入力要素 [type="file"] を使用する場合のスタイルのカスタマイズとブラウザの互換性の問題に関する議論

この2日間、Baixing.comの筆記試験問題を解いているときに、このような問題に遭遇しました。H...

Yahooのフロントエンド最適化に関する35のルールについての簡単な説明

概要: 仕事でも面接でも、Web フロントエンドのパフォーマンスを最適化することは非常に重要です。で...

単純なCSSの詳細に惚れ込むと、重要ではないものの、効率性が向上する可能性がある

CSS の将来は非常に楽しみです。一方では、まったく新しいページ レイアウト方法であり、他方では、ク...

HTML のフォームフォームのメソッド属性の紹介

1 メソッドは、データをサーバーに送信する方法を指定するプロパティです。 2 post と get ...

シームレスなカルーセル効果を実現するネイティブ js

参考までに、ネイティブjsでカルーセル効果(シームレススクロール)を実現しています。具体的な内容は以...

Vue3 でマークダウン エディター コンポーネントを使用する方法

目次インストールコンポーネントのインポート基本的な使い方保存したマークダウンまたは HTML テキス...

mysql 5.7.5 m15 winx64.zip インストール チュートリアル

win7 64 ビットで mysql-5.7.5-m15-winx64 をインストールして構成する方...

HTML の基本 - CSS スタイルシート、スタイル属性、フォーマット、レイアウトの詳細

1.位置:固定一部の Web サイトの右下隅にあるポップアップ ウィンドウなどの、ブラウザーを基準と...

Windows 10 での MySQL 8.0.16 のインストールと設定のチュートリアル

この記事では、参考までにMySQL 8.0.16のインストールと設定方法のグラフィックチュートリアル...

Vueは商品詳細ページの商品タブ機能を実装します

この記事の例では、商品詳細ページ機能を実現するためのVueの商品タブの具体的なコードを参考までに共有...

JavaScriptにおけるPromiseの使い方と注意点について(推奨)

1. 約束の説明Promise は、非同期操作の最終状態 (失敗または正常完了) とその結果の値を...

Linux nlコマンドの使い方

1. コマンドの紹介nl (行数) は指定されたファイルに行番号を追加し、標準出力に書き込みます。フ...

CSS で background-color を使用して背景画像にマスク効果を追加する 2 つの方法

div で background-color と background-image を同時に設定する...

JavaScript でシンプルな Web 時計を実装する

JavaScript を使用して Web ページ クロックを実装します。効果は次の図に示されています...