LoginSignup
1

More than 5 years have passed since last update.

MDNでtemplateとslotの使い方について学ぶ

Posted at

ゴール

MDNを見ながらtemplateとslotについて知ったつもりになる。

参考

template と slot の使い方 - Web Components | MDN

The truth about templates

書いてあるサンプルのHTMLのみ書いてブラウザで表示してみる。

<template id="my-paragraph">
  <p>My paragraph</p>
</template>

おー!表示されない(`・ω・´)
Javascriptを読み込んで.jsに以下を記述。

let template = document.getElementById('my-paragraph');
let templateContent = template.content;
document.body.appendChild(templateContent);

おー!表示された(`・ω・´)
見えないtemplateを用意しておいて、動的に生成できるって感じですかね。

Using templates with web components

.js.htmlを以下のように書き換えて実行。

// javascript
customElements.define('my-paragraph',
  class extends HTMLElement {
    constructor() {
      super();
      let template = document.getElementById('my-paragraph');
      let templateContent = template.content;
      const shadowRoot = this.attachShadow({mode: 'open'})
      .appendChild(templateContent.cloneNode(true));
    }
  }
);
// html
<template id="my-paragraph">
  <style>
    p {
        color: white;
        background-color: #666;
        padding: 5px;
    }
  </style>
  <p>My paragraph</p>
</template>
<my-paragraph></my-paragraph>

おぉ〜...?ってことで1つずつ見ていきます。

HTMLの方はtemplateが用意されているだけですね。.jsの読み込みをしなければ画面上、何も表示されません(my-paragraphタグは表示されます)。

続いて.jsの方を見ていきます。
customElements.defineでカスタムタグを作成は問題無しですね。HTMLElementを継承したクラスを引数に与えているのもOK。id="my-paragraph"のcontentをtemplateContent変数に入れてるのもOK。
cloneNodeをしてるのは複製しないと2度以上使えないから。とは言え動かした結果から言ってるので何でcloneNodeが必要なのかは理解できてない:no_good:

Adding flexibility with slots

ここまでのサンプルでは高々1種類のテキストを表示できるのみで、普通の paragraph よりも使えません。

お、おう。

slot はその name 属性で区別されており、template の中で任意のマークアップで slot の内容のデフォルト値を埋めることができます。

...なるほど、わからん:thinking:
ということで何となくの雰囲気で試してみる。

// html
<template id="my-paragraph">
  <slot></slot>
  <slot name="hoge"></slot>
</template>
<my-paragraph>
  <p>name無しのslotに追加される</p>
  <p>ここもname無しのslot要素に追加される</p>
  <p slot="hoge">name="hoge"に追加される</p>
  <p slot="piyo">name="piyo"に追加される(piyoが無いので追加されない)</p>
</my-paragraph>
// javascript
customElements.define('my-paragraph',
  class extends HTMLElement {
    constructor() {
      super();
      let template = document.getElementById('my-paragraph');
      let templateContent = template.content;
      const shadowRoot = this.attachShadow({
          mode: 'open'
      })
      .appendChild(templateContent.cloneNode(true));
    }
  }
);

こういう理解であってるんだろうか...:thinking:

おわり

何となくわかった気にはなれた。気がする。
Vue.js触ってみようかな。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1