はじめに
簡単に使えることが魅力のVue.jsにおいて、
最初の関門になるものの1つがスロット(slot)だと思います。
特に、スコープ付きスロットは、
理解が難しく感じる人が少し多い気がするので、
私なりの理解について書こうと思います。
スロット(slot)について
まずは、スロットについてのおさらいです。
スロットは、特定領域の描画内容を、
親のコンポーネントにまるまるお願いしたい時に使います。
夕飯の献立を「体が温まるものが食べたい〜」と母親に伝えて、
実際に何を作るかは母親に任せるようなイメージです。
実際にコードで表すと、こんな感じでしょうか。
<template>
<div>
<h2>今日の献立</h2>
<slot name="hot-meal"></slot>
</div>
</template>
それを使う親コンポーネント
<template>
<div>
<my-child>
<template v-slot:hot-meal>
<h3>たまごスープ</h3>
<p>賞味期限が過ぎた卵のたまごスープ</p>
</template>
</my-child>
</div>
</template>
このように子コンポーネントの<slot name="hot-meal">
で指定した領域に、
親コンポーネントからv-slot:hot-meal
の形式でslotのnameを指定することで
描画内容をまるまる渡すことができます。
ちなみに、slotが1つの場合はnameを省略することもできます。
スコープ付きスロットについて
スロットについておさらいしたところで、
次は本題のスコープ付きスロットについてです。
スコープ付きスロットは、
子コンポーネントが持つデータをスロット内において、
親が使うことを許可する仕組みです。
子供が卵を持っていると考えてください。
夕飯の時にこの卵を使ってくれてもいいなと思ってたとします。
その場合に、「この卵、使ってもいいよ」と卵に張り紙を貼っておくイメージです。
コードで説明します。
子コンポーネントのslotタグにおいて、
eggという名前で、eggというデータをバインドしています。
このバインドされた属性は、スロットプロパティと呼ばれています。
<template>
<div>
<h2>今日の献立</h2>
<slot name="hot-meal" v-bind:egg="egg"></slot>
</div>
</template>
script側はこんな感じです。
<script>
export default {
data(){
return {
egg: 'うずらの卵'
}
}
}
</script>
そして親コンポーネントでは、スロットプロパティを通して、
子コンポーネントのデータを使う事ができます。
下の例だと、slotPropsという名前で、スロットプロパティを受け取っていますが、
slotPropsという名前でなくても任意の名前を使えます。
<template>
<div>
<my-child>
<template v-slot:hot-meal="slotProps">
<h3>たまごスープ</h3>
<p>{{ slotProps.egg }}のたまごスープ</p>
</template>
</my-child>
</div>
</template>
このように、子コンポーネントのeggというデータを受け取ることができています。
まとめ
- slotは、親に描画内容を任せるためのもの
- スコープ付きスロットは、親に描画で使える材料を渡すためのもの
おわりに
「スコープ付きスロットっていうわかりづらい概念があるから、Vue.js使うのやめよう」という人が減ればいいなと思います。(そんな人いないか..)
参考