見出し画像

【Nuxt.js】$slotsを使ってみよう

#vue #nuxt #プログラミング #エンジニア

🎈 WPでも公開中です
https://wp.me/pc9NHC-1iY

前置き

あまり見かけない$slotsのご紹介🌟

$slotsはVue公式の
render関数で使用されています。

vm.$slots のアクセスは、描画関数 によるコンポーネントを書くときに最も便利です。
vm.$slots

ただrender関数はNuxtでやるのは
結構むずかしいです💥
なのでrender関数を使用しない
実用的な$slotsの使用例をご紹介します。

同時にrender関数については
何をしたい時に使うか、
そしてNG例をご紹介します。

参考:
描画関数とJSX
【Vue.js】コンポーネントのtemplateの書き方まとめ


$slots

vm.$slots
デフォルトとエラー時などで
表示を切り替えたい際に便利です✨
見てもらった方が早いと思います👀

<template>
 <span v-if="$slots.default">
   <slot />
 </span>
 <span v-if="$slots.error">
   <slot name="error" />
 </span>
</template>
<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を使えばできるんです🍀

⬇️スコープ付きスロットなどは
 こちらをご覧ください👀


描写(render)関数

前置きでも書きましたが、
Nuxtでこれを使うのは
結構むずかしいです💥

できること、NG例を
ご紹介します。

公式のコードをNuxtに置き換えます。
levelというpropsによって
h1〜h6のどれを表示させるか…
コードはこうなります。
長いし、slotが重複してしまいます。
これを省略できるのがrender関数です。

<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を指定

<template>
 <div class="page">
   <AnchoredHeading :level="4">levelを指定</AnchoredHeading>
 </div>
</template>

画像1


##NG例①Vue公式をコピペ

描画関数とJSX
こちらのrender関数をコピペしても
Nuxtでは動きません。

<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は入らなそうなのと、
そもそも動きません。

<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関数内だけでなく
使用ができて便利ですね🌟

🎈 WPでも公開中です
https://wp.me/pc9NHC-1iY

この記事が気に入ったらサポートをしてみませんか?