今回はスロットコンテンツの適応のされ方メモ
下記のようにvueでテンプレートを定義する。
var MyPage = {
template: `
<div class="slottest">
<!-- 親からheader属性のスロット(slot="header")指定時に置き換えられる -->
<header><slot name="header"></slot></header>
<!-- 単一スロットとして扱われ、属性を指定しなかったコンテンツに置き換えられる -->
<main><slot></slot></main>
<!-- 親からfooter属性のスロット(slot="footer")指定時に置き換えられる -->
<footer><slot name="footer"></slot></footer>
</div>
`
}
new Vue({
// id=app配下ではコンポーネント定義したカスタムタグを使えるようにする
el: '#app',
components: {
MyPage: MyPage
}
})
挙動の確認がてらパターンを試してみた。
コンポーネント複数呼び出したもの
<div style="border: 1px solid">
<!-- headerのみ置き換えられる -->
<my-page><h3 slot="header">Header</h3></my-page>
<!-- 単一スロットとして扱われてmainのみ置き換えられる -->
<my-page><p>main01</p></my-page>
<!-- footerのみ置き換えられる -->
<my-page><h3 slot="footer">footer</h3></my-page>
<!-- 単一スロットとして扱われてmainのみ置き換えられる -->
<my-page><p>main02</p></my-page>
<!-- 置き換えが発生しない-->
<my-page><p slot="invalid">main03</p></my-page>
</div>
# 01の出力結果はテンプレート5回呼び出してて長いので流石に省略
存在しないスロット指定のみならカスタムコンポーネントのテンプレートがそのまま表示されるようで
# 存在しないスロット指定したら単一スロットにいくかな~って思ってたんですが、単純に考えればslot属性指定している時点で単一スロット(名前なしスロット)として扱われるわけがないですよね。。。
<div style="border: 1px solid">
<my-page>
<!-- headerを置き換える -->
<h3 slot="header">Header</h3>
<!-- 単一スロットを置き換える -->
<p>main04</p>
<p>main05</p>
<!-- 名前付きスロットでも複数指定時の挙動は単一スロットと同じ -->
<h3 slot="footer">footer01</h3>
<h3 slot="footer">footer02</h3>
<!-- コンテンツ内にfooterスロットを指定しているが単一スロットになる。 -->
<p>main06 <span slot="footer">span footer</span></p>
<!-- 存在しないスロットなので置き換えは行われない -->
<p slot="invalid">main07</p>
</my-page>
<div style="border: 1px solid;">
<div class="slottest">
<header>
<h3>Header</h3>
</header>
<main>
<div class="main">
<p>main04</p>
<p>main05</p>
<p>main06 <span slot="footer">span footer</span></p>
</div>
</main>
<footer>
<h3>footer01</h3>
<h3>footer02</h3>
</footer>
</div>
</div>
呼び出し02の結果から、スロット指定なしのタグ配下にスロット指定タグを入れても、名前付きスロットとしては扱われないで、単一スロットとして扱われていることから、スロット指定有無の判断は恐らくカスタムタグ直下のネストだけみたい
# 流石にネスト深くまでスロット指定みてたらスパゲッティになる未来しか見えませんね。。。
また、結果からスロットに対する考え方が間違ってたとわかったのでメモを残します
スロットの考え方
( <slot></slot> = contents ) * n
下記例みたいな感じで<slot>:<置き換えコンテンツ>=1:1だと思ってたんですよ。
new Vue({
el: '#app',
components: {
customeTag: {
template: '<div><slot name="xxx"></slot></div>'
}
}
})
<custom-tag>
<p slot="xxx"> cont01 </p>
<p slot="xxx"> cont02 </p>
</custom-tag>
<div><p>cont01</p></div>
<div><p>cont02</p></div>
<div><p>cont01</p><p>cont02</p></div>
結果から読み取れる限り下記みたいにスロット事にグルーピングしてから<slot></slot>に置き換えているっぽい
<custom-tag>
<div>cont01</div>
<div slot="xxx">cont02</div>
<div>cont03</div>
<div slot="yyy">cont04</div>
</custom-tag>
単一スロットへの置き換えコンテンツ = <div>cont01</div> , <div>cont03</div>
xxxスロットへの置き換えコンテンツ = <div>cont02</div>
yyyスロットへの置き換えコンテンツ = <div>cont04</div>
つまりこう考えればよさそう
<slot></slot> = [contents01, contents02, contents03, ...]
何か間違えてたらご指摘お願いいたします!
備忘録
過去記事の失敗例のものは単純に、単一スロットを定義していないから置き換えれねーぞってなって置き換えが行われなかっただけですねこれ
https://qiita.com/ysk-kita/items/0c5874fb97f8a08fdc9d