插槽(Slots)是 Vue.js 框架中的一个功能,允许在组件内部预留一些可替换的内容。通过插槽,可以给父组件填充模板代码,让父组件向子组件传递自定义的内容,以便在子组件中进行展示或处理。
1. 匿名插槽
Son.vue
<template>
  <div>
    <header class="header"></header>
    <main class="main">
      <slot></slot>
    </main>
    <footer class="footer"></footer>
  </div>
</template>
<script setup lang="ts">
</script>
<style scoped>
.header {
  height: 200px;
  background-color: red;
  color: white;
}
.main {
  height: 300px;
  background-color: blue;
  color: white;
}
.footer {
  height: 200px;
  background-color: green;
  color: white;
}
</style>
App.vue
<template>
  <div class="content">
    <Son>
      <template v-slot>
          <div>插入中间</div>
      </template>
    </Son>
  </div>
</template>
<script setup lang="ts">
import Son from './components/Son.vue'
</script>
<style scoped>
</style>

2. 具名插槽
Son.vue
<template>
  <div>
    <header class="header">
      <slot name="header"></slot>
    </header>
    <main class="main">
      <slot></slot>
    </main>
    <footer class="footer">
      <slot name="footer"></slot>
    </footer>
  </div>
</template>
<script setup lang="ts">
</script>
<style scoped>
.header {
  height: 200px;
  background-color: red;
  color: white;
}
.main {
  height: 300px;
  background-color: blue;
  color: white;
}
.footer {
  height: 200px;
  background-color: green;
  color: white;
}
</style>
App.vue
<template>
  <div class="content">
    <Son>
      <template v-slot:header>
          <div>插入上面</div>
      </template>
      <template v-slot>
          <div>插入中间</div>
      </template>
      <template v-slot:footer>
          <div>插入下面</div>
      </template>
    </Son>
  </div>
</template>
<script setup lang="ts">
import Son from './components/Son.vue'
</script>
<style scoped>
</style>

3. 插槽作用域
Son.vue
<template>
  <div>
    <header class="header">
      <slot name="header"></slot>
    </header>
    <main class="main">
      <div v-for="(item,index) in data">
        <slot :index="index" :data="item"></slot>
      </div>
    </main>
    <footer class="footer">
      <slot name="footer"></slot>
    </footer>
  </div>
  
</template>
<script setup lang="ts">
import { reactive } from 'vue';
type names = {
  name: string,
  age: number
}
const data = reactive<names[]>([
  {
    name: '张三', 
    age: 18
  },
  {
    name: '李四',
    age: 19
  },
  {
    name: '王五',
    age: 20
  }
])
</script>
<style scoped>
.header {
  height: 200px;
  background-color: red;
  color: white;
}
.main {
  height: 300px;
  background-color: blue;
  color: white;
}
.footer {
  height: 200px;
  background-color: green;
  color: white;
}
</style>
App.vue
<template>
  <div class="content">
    <Son>
      <template v-slot:header>
      <!-- 简写为:#header -->
        <div>插入上面</div>
      </template>
      <!-- 直接解构出 data index -->
      <template v-slot="{ data, index }">
      <!-- 匿名插槽简写为:#default="{ data, index }" -->
        <div>{{ data.name }}--{{ data.age }}--{{ index }}</div>
      </template>
      <template v-slot:footer>
        <div>插入下面</div>
      </template>
    </Son>
  </div>
</template>
<script setup lang="ts">
import Son from './components/Son.vue'
</script>
<style scoped></style>

4. 动态插槽
App.vue
<template>
  <div class="content">
    <Son>
      <template v-slot:[name]>
      <!-- 或者简写为:#[name] -->
        <div>
          我在哪儿?
        </div>
      </template>
    </Son>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Son from './components/Son.vue'
let name = ref('footer')
// let name = ref('deault') // 插入中间的匿名插槽
</script>
<style scoped></style>


![[HDBits] Exams/m2014 q4h](https://img-blog.csdnimg.cn/img_convert/62d78d13e41875f7ecba29f0b2475fd7.png)

















