SvelteでWebコンポーネントを作成する方法


この記事では、Svelteフレームワークを使用してWebコンポーネントを作成する方法を参照してください.
コードを書き始める前に、最初にWebコンポーネントが何かを見ましょう.

Webコンポーネント入門


Webコンポーネントは、WebページやWebアプリケーションで使用するための新しいカスタム、再利用可能でカプセル化されたHTMLタグを作成できるようにWebプラットフォームAPIのセットです.カスタムコンポーネントとウィジェットは、Webコンポーネントの標準に基づいて、現代のブラウザで動作し、任意のHTML互換のJavaScriptライブラリやフレームワークで使用することができます.
Webコンポーネントは、4つの主要な仕様に基づいています.

カスタム要素


カスタム要素は、独自の完全に機能DOM要素を構築する方法を提供します.カスタム要素を定義することにより、著者はパーサにどのように適切に要素を構築するか、どのクラスの要素がどのように変更に反応するかを通知することができます.カスタム要素は、独自のセマンティクス、動作、マークアップを含み、フレームワークやブラウザー間で共有できます.

影ドム


Shadow DOM仕様は、Webコンポーネントにカプセル化されたスタイルとマークアップを使用する方法を定義します.マークアップ構造、スタイル、および動作を隠し続けることができ、別の部分が衝突しないようにページ上の他のコードから分離できます.

モジュール


ESモジュール仕様は、標準ベースの、モジュラー、実行可能な方法でJS文書の包含と再利用を定義します.JavaScript仕様は、モジュールのための構文を定義します、そして、彼らの処理モデルのいくつかのホスト不可知部分.この仕様は他の処理モデルを定義しています.モジュールシステムがブートストラップされているのは、type属性をモジュールに設定したスクリプト要素、モジュールの取得、解決、実行方法です

HTMLテンプレート


HTMLテンプレート要素の仕様は、ページロードで未使用のマークアップのフラグメントを宣言する方法を定義しますが、実行時に後でインスタンス化できます.
Webコンポーネント技術は、独立して、または集合的に使用することができます.

どのように、私はウェブ構成要素を使いますか?


Webコンポーネントの使用は非常に簡単です.たとえば、次のコンポーネントのような、ポリマーから解放されたWebコンポーネントのライブラリに存在するコンポーネントを使用することができます.
https://www.webcomponents.org/element/@polymer/paper-button
簡単なWebページから始める
<!doctype html>
<html>
  <head>
    <title>This is the title of the webpage!</title>
  </head>
  <body>
      <h1>Test Page</h1>
      <p>This is an example paragraph.</p>
  </body>
</html>
これは、Webコンポーネントを含むスクリプトをインポートして、ライブラリコンポーネントを使用するスクリプトを、これが単純なHTML要素であるかのようにインポートできます.
<html>
  <head>
    <title>This is the title of the webpage!</title>
    <script type="module" src="https://npm-demos.appspot.com/@polymer/[email protected]/paper-button.js?@polymer/[email protected]"></script>
  </head>
  <body>
      <h1>Test Page</h1>
      <p>This is an example paragraph.</p>
      <paper-button raised class="indigo">button</paper-button>
  </body>
</html>

Svelteって何?


SvelteはJavaScriptフレームワークリッチハリスによって書かれています.Svelteアプリケーションには、フレームワーク参照が含まれていません.
伝統的なフレームワークが反応するように、Vueや角度は、ブラウザでの仕事の大半を行う、Svelteシフトは、コンパイル時には、アプリケーションを構築するときに発生する動作します.
SvelteはDOMを操作するコードを生成します.
仮想DOMの拡散のようなテクニックを使用する代わりに、Svelteはあなたのアプリケーションの状態が変更されたときに外科的にDOMを更新するコードを書き込みます.

The Svelte implementation of TodoMVC weighs 3.6kb zipped. For comparison, React plus ReactDOM without any app code weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.

  • Introducing Svelte: Frameworks without the framework

シンプルなWebアプリケーションの作り方


新しいSveletプロジェクトを作成するには、公式テンプレートhttps://github.com/sveltejs/templateから始めることができます.
マイSveletプロジェクトディレクトリに新しいプロジェクトを作成するには、その依存関係をインストールし、サーバーを起動すると、次のコマンドを入力できます.
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
npm install
npm run dev
URL http://localhost:5000にアクセスすることによって、あなたはHello Worldウェブアプリを見ます.
この例では、クロックコンポーネントを作成します.ファイルアプリケーションの内容をコピーできます.このリンクからのSvelte:https://svelte.dev/examples#clock.

カスタム要素へのコンパイル(別名: Webコンポーネント)


カスタムコンポーネント(別名、Webコンポーネント)にSlentElementをコンパイルすることもできます.svelte:options要素を使用して、コンポーネントのタグ名を指定する必要があります.
<svelte:options tag="my-element">
既定では、カスタム要素はアクセサーでコンパイルされます.trueは、すべての小文字がDOM要素のプロパティとして公開されることを意味します.これを防ぐには、アクセッサ={ false }をsvelte:optionsに追加します.
カスタム要素にビルドするには、次の手順を実行します.
  • カスタム要素を追加します.設定.jsファイル
  •     plugins: [
            svelte({
                customElement: true,
    
  • アドインアプリケーション.スベルト
  • <svelte:options tag="svelte-clock">
    
    このsvelteを定義しない場合、コンパイラは次のメッセージを警告します
    svelte plugin: No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/
    
  • は「NPMランビルド」
  • を走らせます
    開発中に(NPMの実行dev)、ライブリロードが有効になります.つまり、カスタム要素またはHTMLに対して変更された変更は、すぐにブラウザに反映されます.
    Webコンポーネントの準備ができたら、“NPM Run Build”を実行することができます.jsファイル.
    コンパイラはシャドウDOMを作成し、属性/プロパティを適用し、カスタム要素を定義します.
    作成したWebコンポーネントをテストするには、HTTPサーバーを利用できます.
    インストールするには、次のコマンドを実行できます.
    npm install http-server -g
    
    次に、パブリックディレクトリにインデックスを作成できます.HTMLをインポートします.カスタム要素"svelte clock "を宣言します.
    <!doctype html>
    <html>
      <head>
        <title>This is the title of the webpage!</title>
        <script src="bundle.js"></script>
      </head>
      <body>
          <h1>Test Page</h1>
          <p>This is an example paragraph.</p>
          <svelte-clock/>
      </body>
    </html>
    
    次のコマンドを実行すると、コンポーネントが動作します.
    > http-server -p 8080 -c-1 public/
    Starting up http-server, serving public/
    Available on:
      http://127.0.0.1:8080
    

    SvelTe Webコンポーネント:結論


    プロパティ


    カスタム要素が受け入れるすべての小道具は、コンパイル時に自動的に要素属性に変換されます.camelcaseやpascalcaseのような命名規則はHTMLでは動作しません.
    テストするには、カスタム要素に単純なプロパティを追加できます.
    <script>
        ...
        export let clocktitle = "Svelte Clock"
        ...
    </script>
    ...
    <h1>{clocktitle}</h1>
    ...
    
    我々のインデックスで.HTMLは現在値を設定することができます
    <svelte-clock clocktitle="My Clock"></svelte-clock>
    

    イベント


    Webコンポーネントとしてラップされたsvelte 3内から生成されたカスタムイベントは、通常のDOMイベントとしてWebコンポーネント自体にバブルアップしません(既定でのカスタムイベントは、影の境界を過ぎて行くことはありません)テンプレート内の通常の方法で処理することはできません.
    <svelte-clock custom-event="handler()">    
    

    カスタム要素にコンパイルされたコンポーネントからイベントは発生しません 菅3119



    vogloblinsky

    イベントを聞くためのネイティブのsvelte構文:myCustomEventは、カスタム要素にエクスポートされたsvelteコンポーネントによってディスパッチされたイベントで動作しません.
    これに関連しているかもしれません?https://github.com/sveltejs/svelte/blob/a0e0f0125aa554b3f79b0980922744ee11857069/src/runtime/internal/Component.ts#L162-L171
    再生リポジトリはこちら
    https://github.com/vogloblinsky/svelte-3-wc-debug

    SVLT 3生


    svelte構文を使用する例.内部コンポーネントディスパッチカスタムイベント'メッセージ'.アプリケーションコンポーネントを使用して
    動く!
    //Inner.svelte
    <script>
        import { createEventDispatcher } from 'svelte';
    
        const dispatch = createEventDispatcher();
    
        function sayHello() {
            console.log('sayHello in child: ', 'Hello!');
            dispatch('message', {
                text: 'Hello!'
            });
        }
    </script>
    
    <button on:click={sayHello}>
        Click to say hello
    </button>
    
    //App.svelte
    <script>
        import Inner from './Inner.svelte';
    
        function handleMessage(event) {
            console.log('handleMessage in parent: ', event.detail.text);
        }
    </script>
    
    <Inner on:message={handleMessage}/>
    

    Svelet 3 WC


    Svelte構文を使用してコンポーネントをWebコンポーネントにエクスポートする例.内部コンポーネントディスパッチカスタムイベント'メッセージ'.アプリケーションコンポーネントを使用して
    同じ構文は動作しません.
    //Inner.svelte
    <svelte:options tag="inner-btn"/>
    <script>
        import { createEventDispatcher } from 'svelte';
    
        const dispatch = createEventDispatcher();
    
        function sayHello() {
            console.log('sayHello in child: ', 'Hello!');
            dispatch('message', {
                text: 'Hello!'
            });
        }
    </script>
    
    <button on:click={sayHello}>
        Click to say hello
    </button>
    
    //App.svelte
    <svelte:options tag="my-app" />
    <script>
        import Inner from './Inner.svelte';
    
        function handleMessage(event) {
            console.log('handleMessage in parent: ', event.detail.text);
        }
    </script>
    
    <inner-btn on:message={handleMessage}/>
    
    バニラJSはパブリック/インデックスで動作します.HTML
    const button = document
                        .querySelector('my-app')
                        .shadowRoot.querySelector('inner-btn');
    
                    button.$on('message', e => {
                        console.log('handleMessage in page');
                    });
    
    View on GitHub
    Shadowdomの境界線を越えるために、SvelteのV 2ドキュメントで述べたようにカスタムイベントを作成しなければなりません.CustomEvent APIを使用してSvelteコンポーネントでカスタムイベントを作成できます.カスタムイベントを定義した後、このイベントを呼び出すことでイベントをディスパッチできます.DispatchEvent(イベント)コンポーネントの変更に応答します.
    カスタムイベントは、ライフサイクルメソッドに応じてディスパッチできません.たとえば、Onmount LifeCycleメソッドでカスタムイベントをディスパッチしようとすると、イベントはディスパッチされません.
    イベントを追加するには、ボタンを追加できます.
    <button on:click="{dispatchSavedDateEvent}">Save Date</button>
    
    クリックすると、カスタムイベントを生成できます.
    function dispatchSavedDateEvent(e) {
       console.log("[dispatchSecondIsElapsedEvent] time: ", time);
       // 1. Create the custom event.
       const event = new CustomEvent("savedData", {
         detail: time,
         bubbles: true,
         cancelable: true,
         composed: true // makes the event jump shadow DOM boundary
       });
    
       // 2. Dispatch the custom event.
       this.dispatchEvent(event);
     }
    
    イベントインターフェイスの読み取り専用のプロパティは、イベントがシャドウDOM境界を越えて標準DOMに伝播するかどうかを示すBooleanを返します.
    別の方法は、CreateEventDispatcherを利用することです
    import { createEventDispatcher } from 'svelte'; 
    const dispatch = createEventDispatcher();
    ...
    dispatch('second', {
           text: '10 seconds elapsed!'
         });
    ...
    
    インデックスで.HTMLは次のように新しいイベントを購読しなければなりません.
    document.querySelector('svelte-clock')
        .$on('second', (e) => { console.log("[index.html][second]", e)})
    

    輸入


    svelteコンポーネントをインポートするには、各ネストされた要素をタグで宣言する必要があります
    <svelte:option tag="my-nested-element”>
    
    子要素をカスタム要素として宣言すると、これらの要素は消費者にも利用できます.
    入れ子にされた要素は親として同じ影DOMを使用します、ネストされた要素のためにシャドウDOMモードを「閉じた」に設定する方法がありません.
    Svelteを使用する主な利点.Webコンポーネントを作成するためのJSは、最後のコンポーネントが非常に小さな次元を持っていることです.小さな例では、バンドル内にパッケージ化されたWebコンポーネントがあります.JSは、7170バイトだけで、他のフレームワークによって作成されたWebコンポーネントと比較して、Webコンポーネントを何十倍も小さくなり、ブラウザによって実行されるようになります.