🗒️
【Nuxt.js v2】v-slotの指定方法
デフォルトスロットの指定
<template v-slot:default>・・・</template>
<!-- デフォルトスロットの場合はスロット名を省略できる。 -->
<template v-slot>・・・</template>
<!-- v-slot自体も省略できる。 -->
<template>・・・</template>
名前付きスロット
<!-- 名前付きスロット -->
<template v-slot:header>・・・</template>
<!-- v-slot:は#で省略できる。 -->
<template #header>・・・</template>
<!-- v-slotを省略したデフォルトスロットと、共存できる。 -->
<template>・・・</template>
<template #header>・・・</template>
スロットプロパティ
<div>
<slot :name="name">
{{ name }}
</slot>
</div>
上記のように定義されたスロットプロパティを、以下のように利用側(親コンポーネント)で参照できる。
任意の変数名(以下のprops)で受け取り、その変数のプロパティとして格納されている。
<template #default="props">
{{ props.name }}
</template>
以下のように分割代入を使用すれば、スロットプロパティをそのまま受け取れるため、記述が簡素になる。
<template #default="{ name }">
{{ name }}
</template>
スロットプロパティに別名をつけることが可能
同じスコープ内で他のプロパティや変数と名前が被ってしまう場合に使える。
(以下ではnameというプロパティをuserNameという名前につけかえて取得)
<template #default="{ name: userName }">
{{ userName }}
</template>
動的なスロット名
変数の値で動的にスロット名を指定できる。
(v-slot:は#で省略)
<!-- 変数slotNameに指定したいスロット名を格納している。 -->
<template #[slotName]>・・・</template>
以下のパターンは、itemオブジェクトのnameに格納された文字列をスロット名として指定している。
<template #[item.name]>・・・</template>
特殊なパターン
slot名に.(ピリオド)が使用されている場合は以下のようにする。
自作のコンポーネントではまず無いが、Vuetifyのv-data-tableを使用する際にこのような記述を必要とする場合がある。
<template #item.name>・・・</template>
ESLintを導入していて'v-slot' directive doesn't support any modifier
というエラーが出る場合は、以下のように書き換える。
<template #[`item.name`]>・・・</template>
※ なぜこうなるか
- ピリオドが、v-onで使用するイベント修飾子と認識されてしまい、「'v-slot'は修飾子をサポートしてないよ!」と指摘される。(イベント修飾子の例→
v-on:click.stop
) - ピリオドを含め文字列として認識させるために、[]での動的スロット名に文字列を渡すことで解決する。
- 動的なスロット名指定に、普通のクオーテーションで囲んだ文字列を渡すと、以下のエラーが発生する。
Invalid dynamic argument expression: attribute names cannot contain spaces, quotes, <, >, / or =.
(動的引数式に引用符などは含められない。) - ``(バッククオーテーション)を使用したテンプレート構文で文字列を渡せば上記エラーは解決する。
このようにして、#[`item.name`]
となる。
Discussion