0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

🎈 この記事は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>
index.vue
<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関数です。

AnchoredHeading.vue
<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を指定

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

image.png

NG例①Vue公式をコピペ

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

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

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?