Web コンポーネントの内部イベント コールバックと問題点の分析

Web コンポーネントの内部イベント コールバックと問題点の分析

前面に書かれた

最近、Web コンポーネント (WC) に取り組んでおり、いくつかの初期成果を達成しました。しかし、今日は WC をもう一度見ていきたいと思います。

WC とは何でしょうか?

簡単に言えば、Web コンポーネントはコンポーネントを HTML タグの形式でカプセル化し、使用時に追加の JS コードは必要ありません。

コンポーネントはフロントエンドの開発方向です。周囲のテクノロジーエコシステムを別にすれば、React と Vue はどちらもコンポーネントフレームワークです。したがって、WC は元のラベルの延長として見ることができます。結局のところ、それはまだラベルです。

<video></video>タグと同様に、ネイティブ タグよりも多くのスタイルと操作属性があります。

Google は Chrome ブラウザを管理しているため、ブラウザのネイティブ コンポーネント、つまり Web コンポーネント API を推進してきました。

サードパーティのフレームワークと比較すると、ネイティブ コンポーネントはシンプルで直接的かつ直感的であり、外部モジュールをロードする必要がなく、コード量も少なくなります。すべてが完璧で、React、Vue などの置き換えにも使えるようです。

現在の欠陥

他の Web フレームワークと併用すると、いくつかの小さな問題が発生し、開発エクスペリエンスに問題が発生する可能性があります。

1. コンポーネント内部イベントのコールバック

たとえば、ポップアップ コンポーネント ( <my-dialog></my-dialog> ) の [OK] ボタンの場合、そのイベントはどのようにトリガーされますか?

クラスmyDialogはHTMLElementを拡張します{
  // ...
  接続されたコールバック() {
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.innerHTML = `
      <div class="ダイアログ">
        <div class="ダイアログコンテンツ">
          <div class="ダイアログボディ">
            ポップアップコンテンツ</div>
 
          <button id="okBtn">OK</button>
        </div>
      </div>
    `;
     shadowRoot.querySelector('#okBtn').addEventListener('click', () => {
      // コンポーネント内のイベントを定義します this.dispatchEvent(new CustomEvent('okBtnFn'));
    });
  }
} 
customElements.define('my-dialog', myDialog);

現在の解決策は、カスタム要素内でnew CustomEvent()を使用し、 addEventListenerを使用して外部でリッスンすることです。この書き方は非常に醜く、まるでネイティブ JS を使用してアプリケーションを作成する時代に戻ったかのようです。

<私のダイアログ></私のダイアログ> 
<スクリプト>
  エクスポートデフォルト{
    作成された() {
      document.addEventListener('okBtnFn', 関数(){
        // ポップアップボタンをクリックしてコールバックイベントをトリガーします});
    }
  }
</スクリプト>

2. コンポーネントスタイルの範囲

開発者にとって、コンポーネントの内部スタイルを調整する必要が生じるのは避けられません。 antdvant 、またはその他のコンポーネント ライブラリを使用する場合でも、WC の CSS 汚染防止メカニズムにより、内部スタイルを変更することが困難になります。内部スタイルを偽装するためには、いくらかの代償を支払う必要がある

3. コンポーネント内の内部リソースの相対パス問題

現在、カスタム要素 v1、テンプレート、HTML インポートを直接ベースとするコンポーネントは、ユーザーの環境を認識せずに、またユーザーに追加の制限を加えずに、内部的にカプセル化されたリソース ファイルを使用することで、完全にリソースに依存しないことはできません。たとえば、カスタム アイコン コンポーネントがある場合:

クラス MyIcon は HTMLElement を拡張します {
    静的に観測属性を取得します(){['name','size','color']を返します}
    コンストラクタ() {
        素晴らしい();
        const shadowRoot = this.attachShadow({ mode: 'open' });
        shadowRoot.innerHTML = `
            <svg class="icon" id="icon" aria-hidden="true" viewBox="0 0 1024 1024">
                <use id="use"></use>
            </svg>        
    } 
    attributeChangedCallback (名前、古い値、新しい値) {
        if(name == 'name' && this.shadowRoot){
            // 使用中のプロジェクトのルートディレクトリにicon.svgファイルがない場合、gg
            this.use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `./icon.svg#icon-${newValue}`);
        }
    }
}
customElements.define('my-icon', MyIcon);

使用しているプロジェクトのルート ディレクトリに icon.svg ファイルがない場合、gg です。ここで CDN パスを使用すると、クロスドメインの問題が発生します。

4. フォームコンポーネント値取得問題

Shadow DOM 内の <input>、<textarea>、または <select> タグの値は、フォームに自動的に関連付けられません。

サンプルコード:

// ウェブコンポーネント
クラス InputAge は HTMLElement を拡張します {
  コンストラクタ() {
    素晴らしい();
  }  
// コンポーネントを接続する
  接続されたコールバック() {
    const shadow = this.attachShadow({ mode: 'closed' });
    shadow.innerHTML = `<input type="number" placeholder="age" min="18" max="120" />`;
  }
}
// コンポーネントを登録する
customElements.define( '入力年齢', InputAge );

WCコンポーネントを使用した後

<フォームid="myform">
  <input type="text" name="あなたの名前" placeholder="名前" />
  <input-age name="あなたの年齢"></input-age>
 
  <button>送信</button>
</フォーム>
 
<スクリプト>
 定数フォーム = document.getElementById('myform');
 
  フォーム.addEventListener('送信', e => {
    
    e.preventDefault();
    console.log('送信されたデータ:');
 
    const データ = 新しい FormData(フォーム);
    for (let nv of data.entries()) {
      コンソールにログ出力します。
    }
 
  });
</スクリプト>

送信時にinput-agevalueを取得できません。もちろん解決策はあるだろうが、それは複雑なものとなるだろう。

5. その他

さらに、データ バインディングと状態管理の欠如も WC の欠陥ですが、ここでは説明しません。

裏面に記入

WCはHTMLのDOM機能を充実させ、HTMLの再利用性を高めることを指します。

WC はネイティブ タグとして使用でき、任意のフロントエンド フレームワークで実行することも、フレームワークなしで実行することもできます。

現在の主流のテクノロジー スタックと組み合わせた場合、WC の主な問題は、複雑なコンポーネントでは、データ通信とイベント配信に一定の使用コストがかかることです。

内部スタイルを上書きできる:partメソッドなどの互換性の問題

上記は、Webコンポーネントの内部イベントコールバックと問題点分析の詳細な内容です。Webコンポーネントのイベントコールバックと問題点の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vueの組み込みコンポーネントの適用シナリオについての簡単な説明
  • @Componentアノテーションによって生じた大きな落とし穴
  • Vueコンポーネントのサードパーティライブラリをカプセル化するためのステップバイステップガイド
  • Angularコンポーネントのソースコード例を分析する

<<:  CentOS 8 システム FTP サーバーのインストールとパッシブ モードの設定の詳細なチュートリアル

>>:  オンラインMySQL自動増分IDが使い果たされた場合の対処方法

推薦する

Ubuntu に MySQL 5.7 をインストールし、データ ストレージ パスを構成する方法

1. MySQLをインストールするこの記事はAPT経由でインストールされており、インストールされてい...

VMWARE で Centos8 仮想マシンをコピーすることによって発生する IP 損失の問題の解決策

VMwareでcentos8サービスをインストールしてコピーすると、次の問題が発生します。 コピー前...

HTML チュートリアル: 画像のサイズ、配置、間隔、境界線の属性を変更する方法

画像タグ: <img> ページに画像を挿入するには、「src」属性を持つ「img」タグを...

VMware+centOS 8 で http プロトコルに基づく Git サービスを構築する方法

目次1. 原因2. デバイス情報3. 準備4. Apacheをインストールする5. gitを設定する...

Linux システムでの virtuoso データベースの詳細なインストールと使用

最近、リンク データについていくつか調査していて、rdf データベースを使用する必要があったため、v...

CentOS 7 で MySQL 5.7 をインストールして設定する

この記事では、以下の環境をテストします。 CentOS 7 64 ビット 最小 MySQL 5.7 ...

Navicat for MySql ビジュアルインポート CSV ファイル

この記事では、参考までに、Navicat for MySql の CSV ファイルのビジュアルインポ...

MySQL でグループ化した後、各グループの最大値を取得する詳細な例

MySQL でグループ化した後、各グループの最大値を取得する詳細な例1. テストデータベーステーブル...

Linuxのバージョン情報を復号化する方法

Linux バージョンに関する情報を表示および解釈するのは、見た目よりも少し複雑です。単純なバージョ...

JS 関数のアンチシェイクと関数スロットリングを理解する方法

目次概要1. 関数デバウンス2. 機能スロットリング(スロットル)概要関数アンチシェイクと関数スロッ...

Linux のごみ箱メカニズムの実装プロセスと使用方法の詳細な説明

序文: Linux システムでの rm は元に戻せません。コマンドの設計自体に問題はありません。問題...

WeChatアプレットの入力レベルとテキストエリアレベルの浸透率が高すぎる問題の解決策

WeChat ミニプログラムのネイティブ コンポーネントであるカメラ、キャンバス、入力 (フォーカス...

モバイルインターネット時代: レスポンシブウェブデザインが一般的なトレンドに

今はモバイルインターネットが急速に発展している時代です。スマートフォンやタブレットはますます普及し、...

MySQLシリーズ マルチテーブル結合クエリ92および99構文例詳細チュートリアル

目次1. デカルト積現象2. 接続クエリの知識ポイントのまとめ1) 結合クエリとは何ですか? 2) ...