今後はv-slotを使いなさいって話のようで。
.section
.section__header
h2 ニュース
.section__body
ul
li
ヘッダーとボディーを持つセクションというのは、とてもよく使います。
.contents
.section
.section
.section
のようにセクション単位でコンテンツを分けたりします。
「ひとかたまりのコンテンツはセクションで囲む」という鉄の掟を作ると、秩序が生まれます。
なのでコンポーネントを作り、これを使うことを遵守します。
<template lang="pug">
.section
.header
slot(name="header")
.body
slot(name="body")
</template>
単一ファイルコンポーネントとして作ります。
.section__headerとか.section__bodyとか書く必要も無くなるので、
クラス名を単純に.headerと.bodyにしてしまいます。
※pug-plain-loaderをインストールしているため、lang="pug"をつけることでPugの記法が使えるようになっています。
<template lang="pug">
Section
template(v-slot:header)
h2 新着ニュース一覧
template(v-slot:body)
ul
li ...
li ...
</template>
<script>
import Section from '@/components/Section.vue'
export default{
components:{
Section
}
}
</script>
呼び出し元のViewです。
template(v-slot:header)の子要素がslot(name="header")に、
template(v-slot:body)の子要素がslot(name="body")に置きかわります。
記述する分量が増えてる疑惑がありますが、
クラス名が気に入らなくなって変えたいといった時でも
/src/components/Section.vueの1箇所を変えるだけで、
全てに適用されるのは魅力だと思います。
(パフォーマンスへの影響は若干気になるところですが)
さて、たまに厄介なのが、広告枠などheaderが要らないケースです。
Section
template(v-slot:body)
iframe
のような場合です。
現状の/src/components/Section.vueは
template(v-slot:header)に子要素がなくても.headerを出力してしまいます。
<div class="section">
<div class="header"><div>
<div class="body">
<iframe></iframe>
</div>
</div>
といった具合に。
空のDOMエレメントが出力されてしまうのが気になるのでv-ifを使って
「template(v-slot:header)がない場合は.headerの部分を出力しない」
という分岐をします。
<template lang="pug">
.section
.header(v-if='this.$slots.header')
slot(name="header")
.body(v-if='this.$slots.body')
slot(name="body")
</template>
のように「this.$slots」をv-ifの条件に使います。
<template lang="pug">
Section
template(v-slot:body)
iframe
</template>
<script>
import Section from '@/components/Section.vue'
export default{
components:{
Section
}
}
</script>
すると、上記のようにtemplate(v-slot:body)がない場合は.headerが出力されなくなります。