Vue.js のスロットまとめ

● スロット1つ

親コンポーネント Parent.Vue

<Childcomponent>
山田太郎
</Childcomponent>

子コンポーネント Childcomponent.Vue

<h1>
 <slot>default name</slot>
</h1>

結果

山田太郎

● スロット複数

親コンポーネント Parent.Vue

<template>
  <SampleslotChild>
    <template #last>山田</template>
    <template #first>太郎</template>
  </SampleslotChild>

  <SampleslotChild>
    <template v-slot:last>テスト</template>
    <template v-slot:first>ジロウ</template>
  </SampleslotChild>

</template>

<script lang="ts" setup>
import SampleslotChild from "./SampleslotChild.vue"
</script>

#lastv-slot:last は同じです、好きな方で記述しましょう

子コンポーネント Childcomponent.Vue

<template>
  <h1>
    <slot name="last">default-last-name</slot>
  </h1>
  <h2>
    <slot name="first">default-first-name</slot>
  </h2>
</template>

結果

山田
太郎
テスト
ジロウ

● スコープ付きスロット(スロットプロパティ)(プリミティブ値)

親コンポーネントから子コンポーネントのデータを参照するスロットプロップス(slotProps)を受け取ることができます string型の position を受け取ってみます

親コンポーネント Parent.Vue

<template>
  <SampleslotChild>
    <template v-slot:position="slotProps">{{ slotProps }}</template>
  </SampleslotChild>
</template>

<script lang="ts" setup>
import SampleslotChild from "./SampleslotChild.vue"
</script>

子コンポーネント Childcomponent.Vue

<template>
  <h3>
    <slot name="position" v-bind:position="position">{{position}}</slot>
  </h3>
</template>

<script lang="ts" setup>
import {ref} from 'vue'

const position = ref("スタッフ")

setTimeout(() => {
  position.value = '更新されたスタッフ'
}, 1000)
</script>

結果

{ "position": "スタッフ" }

  ↓ (1秒後に次のような表示となります)

{ "position": "更新されたスタッフ" }

● スコープ付きスロット(スロットプロパティ)(オブジェクト)

オブジェクトを受け取る場合は次のように記述します

親コンポーネント Parent.Vue

<template>
  <h1>一括で受け取る場合</h1>
  <SampleslotChild>
    <template v-slot:user="slotProps">slotPropsのname:{{ slotProps.user.name }}</template>
  </SampleslotChild>

  <h1>分割代入で受け取る場合</h1>
  <SampleslotChild>
    <template v-slot:user="{user:{name,age}}">slotPropsのname:{{ name }}</template>
  </SampleslotChild>

</template>

<script lang="ts" setup>
import SampleslotChild from "./SampleslotChild.vue"
</script>

子コンポーネント Childcomponent.Vue

<template>
  <h4>
    <slot name="user" v-bind:user="user">{{ user.name }} ({{ user.age }})</slot>
  </h4>
</template>


<script lang="ts" setup>
import {reactive} from 'vue'

interface User {
  name: string
  age: number
}

const user = reactive<User>({
  name: 'スタッフ 太郎',
  age: 20
})

setTimeout(() => {
  user.name = '更新 次郎'
  user.age = 21

}, 1000)
</script>
No.2238
11/17 14:13

edit