前置き
あまり見かけない$slots
のご紹介🌟
$slots
はVue公式のrender関数
で使用されています。
vm.$slots
vm.$slots
のアクセスは、描画関数 によるコンポーネントを書くときに最も便利です。
ただrender関数
はNuxtでやるのは
結構むずかしいです💥
なのでrender関数
を使用しない
実用的な$slots
の使用例をご紹介します。
同時にrender関数
については
何をしたい時に使うか、
そしてNG例をご紹介します。
参考:
描画関数とJSX
【Vue.js】コンポーネントのtemplateの書き方まとめ
$slots
vm.$slots
デフォルトとエラー時などで
表示を切り替えたい際に便利です✨
見てもらった方が早いと思います👀
1 2 3 4 5 6 7 8 |
<template> <span v-if="$slots.default"> <slot /> </span> <span v-if="$slots.error"> <slot name="error" /> </span> </template> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<template> <div class="page"> <TextSlot> <template> {{ text }} </template> <template #error> {{ textError }} </template> </TextSlot> </div> </template> <script> export default { data() { return { text: '通常テキスト', textError: 'エラー時のテキスト', } , } |
スロットを複数使う場合は
名前付きにしていました。
ただslot
の状態によって
表示/非表示をv-if
で
切り替えることはできませんでした💡
それが$slots
を使えばできるんです🍀
⬇️スコープ付きスロットなどは
こちらをご覧ください👀
【Nuxt.js】slot文法編: スコープ付きスロットを使おう
描写(render)関数
前置きでも書きましたが、
Nuxtでこれを使うのは
結構むずかしいです💥
できること、NG例を
ご紹介します。
公式のコードをNuxtに置き換えます。level
というprops
によってh1
〜h6
のどれを表示させるか…
コードはこうなります。
長いし、slot
が重複してしまいます。
これを省略できるのがrender関数
です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<template> <div class="ttl"> <h1 v-if="level === 1"> <slot></slot> </h1> <h2 v-else-if="level === 2"> <slot></slot> </h2> <h3 v-else-if="level === 3"> <slot></slot> </h3> <h4 v-else-if="level === 4"> <slot></slot> </h4> <h5 v-else-if="level === 5"> <slot></slot> </h5> <h6 v-else-if="level === 6"> <slot></slot> </h6> </div> </template> <script> export default { props: { level: { type: Number, required: true, }, }, } </script> |
親でlevel
を指定h4
を表示させたいので4
を指定
1 2 3 4 5 |
<template> <div class="page"> <AnchoredHeading :level="4">levelを指定</AnchoredHeading> </div> </template> |
NG例①Vue公式をコピペ
描画関数とJSX
こちらのrender関数
をコピペしても
Nuxtでは動きません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<template> <div class="ttl"> </div> </template> <script> export default { props: { level: { type: Number, required: true, }, }, render: function (createElement) { return createElement( 'h' + this.level, // タグ名 this.$slots.default // 子の配列 ) }, } </script> |
NG例②
Nuxt render function for a string of HTML that contains Vue components
こちらを参考にやってみます。template
なのでhタグ
の入れ子にslot
は入らなそうなのと、
そもそも動きません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<template> <div class="ttl"> </div> </template> <script> export default { props: { level: { type: Number, required: true, }, }, render(h, context) { return h({ template: `h${this.level}, ${this.$slots.default}` }) }, } </script> |
じゃあ使うためにはどうするか、
今のところJSXを
使うしかなさそうです。
まとめ
$slots
はrender関数
内だけでなく
使用ができて便利ですね🌟