名前付きスロットでコンポーネントの複数のスロットにコンテンツを埋め込む v-slot [Vue.js]

Vue.js The Progressive JavaScript Framework

前回はコンポーネントに外部からコンテンツを埋め込むことができるスロット(slot要素)を紹介しました。

コンポーネントに指定したコンテンツを外から埋め込む<slot>要素 [Vue.js]
コンポーネントを作成していると、コンポーネント側の実装時点では配置できない要素などを利用する側から差し込みたい場合があります。 ...

前回の記事では、slot要素を使用して子コンポーネントに用意したコンテンツを差し込める場所に、親コンポーネントからテキストや任意のHTML要素を挿入しましたが、コンテンツを差し込める場所は1つしかありませんでした。

しかしコンポーネントを作成してれば、スロットによってコンテンツを埋め込む箇所を複数用意したい場合があります。

そこで今回は、1つのコンポーネント内に複数のスロットを用意して親コンポーネントからコンテンツを埋め込む方法について紹介します。

名前付きスロット

1つのコンポーネントに複数のスロットを用意する場合は、それぞれのスロットを判別するためのキーが必要になります。
そこでVue.jsのslot要素には、属性にname名前が指定できるようになっています。

名前付きスロットの書式

名前付きのslot要素を配置する場合は、以下のようにname属性で名前を指定します。

名前付きスロットの記述例

例えば以下のようなHTMLテンプレートがある場合

ヘッダー、メイン、フッターのそれぞれにスロット(slot要素)を配置し、各スロットに名前を付けると次のようになります。

上記のHTMLテンプレートを持つ子コンポーネントを親コンポーネントから参照する場合は以下のようにします。(ここではコンポーネントの名前を「container-component」とします。)

親コンポーネントから子コンポーネントの名前付きスロットにコンテンツを挿入する時は、v-slotディレクティブを使用します。(3行目、7行目、13行目)
ここでは、ヘッダー、メイン、フッターのそれぞれにtemplate要素を配置して、「header」「main」「footer」の名前を付けたスロットにv-slotディレクティブを指定しています。
名前付きスロットを利用する場合は「template要素を配置してv-slotディレクティブで名前を指定」します。
v-slotディレクティブには「v-slot:名前」の形式で引数に名前を指定します。

上記のコードを実行すると、以下のHTMLが出力されます。

表示される画面は以下のようになります。

Vue.js 名前付きスロットをv-slotディレクティブでバインドしたサンプルを実行した結果

上記の例では、すべてのスロットにname属性で名前を付けていますが、name属性は省略することもできます。
name属性を持たないslot要素は、暗黙的に「default」という名前と見なされます。
例えば、上記のmain要素のname属性を省略して以下のようにすると

親コンポーネントのHTMLテンプレートは以下のようにv-slotディレクティブの引数の名前に「default」を指定することができます。

名前を省略したスロットがある場合は、v-slotディレクティブでバインドせずに以下のようにコンテンツを配置すると、名前がスロットにコンテンツが挿入されます。

上記の例では、メインコンテンツをヘッダーとフッターの間に配置していますが、名前が省略されているスロットに埋め込むコンテンツは以下のようにどこに配置しても挿入されます。

v-slotディレクティブの省略記法

v-slotディレクティブには、v-bindディレクティブやv-onディレクティブと同様に省略記法が用意されています。
v-slotディレクティブの省略記法は「#」になります。「v-slot:」の部分を「#」に置き換えることができます。

ディレクティブの省略記法については、以下の記事も参考にしてください。

ディレクティブの省略記法 「v-bind: ⇒ :」「v-on: ⇒ @」[Vue.js]
Vue.jsでは、HTMLテンプレートでディレクティブを使用して、データをバインドしたりDOMを操作したりします。 デ...

v-slotディレクティブの動的引数

v-slotディレクティブでは、v-bindディレクティブやv-onディレクティブと同様に動的引数を利用する事ができます。

ディレクティブの動的引数については、以下の記事も参考にしてください。

ディレクティブ(v-bind, v-on)の動的引数 [Vue.js]
Vue.jsのv-bindディレクティブを使用すると、HTML要素の属性に値をバインドすることができます。 v-bin...

Vue.js 入門 Tips 一覧