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が使い果たされた場合の対処方法

推薦する

CSS マルチカラムレイアウトソリューション

1. 固定幅+適応型期待される効果: 左側は固定幅、右側は適応幅 共通コード: html: <...

Linux での Tomcat8 のインストールとアンインストールに関する詳細なグラフィック チュートリアル

[ Tomcat8 の Linux インストール ] Tomcat をアンインストールする - まず...

テーブルリストを破棄するには、標準のdl、dt、ddタグを使用します。

現在、ますます多くのフロントエンド開発者が、元のテーブル レイアウトを xHTML + CSS に置...

PHP スケジュールバックアップ MySQL および mysqldump 構文パラメータの詳細

まず、MySQL バックアップ コマンド mysqldump の一般的な操作例をいくつか紹介します。...

Docker Compose の実践とまとめ

Docker Compose は、Docker コンテナ クラスターのオーケストレーションを実現しま...

InnoDBのインデックスページ構造、挿入バッファ、適応ハッシュインデックスについての簡単な説明

InnoDB インデックスの物理構造すべての InnoDB インデックスは Btree インデックス...

CentOS 7のインストールと設定方法のグラフィックチュートリアル

この記事は、CentOS 7の詳細なインストールチュートリアルを参考のために記録します。具体的な内容...

mysql 解凍パッケージの基本インストールチュートリアル

新しいコンピューターに変更したので、すべての環境を新しいコンピューター上で設定する必要があります。ふ...

Reactにおけるフックの一般的な使用法

目次1. フックとは何ですか? 2. フックはなぜ現れるのでしょうか? 3. よく使われるフックは何...

Win7 での mysql5.5 インストール グラフィック チュートリアル

MySQL のインストールは比較的簡単なので、通常は次のステップに直接進み、注意が必要な点に集中する...

URL 内の特殊記号の意味を知っていますか?

1.# # は Web ページ内の場所を表します。右側の文字はその位置の識別子です。たとえば、ht...

JavaScript 組み込みの日付と時刻の書式設定のサンプル コード

1. 基礎知識(日付オブジェクトのメソッド) 😜 getFullYear() は年を表す4桁の数字を...

個人履歴書を作成するための HTML の簡単な実装

履歴書コード: XML/HTML コードコンテンツをクリップボードにコピー<!DOCTYPE ...

CSS で div にスクロールを追加し、スクロール バーを非表示にする

CSS は div にスクロールを追加し、スクロール バーを非表示にします。具体的なコードは次のとお...

CSS で画像アダプティブ コンテナを実装するためのサンプル コード

多くの場合、画像をコンテナのサイズに合わせて調整する必要があります。 1. imgタグ方式幅と高さを...