标准答案

  1. 默认插槽用于一个可替换内容区域,例如 Card 的正文。
  2. 具名插槽用于多个区域,例如 header、default、footer,让父组件分别填充不同位置。
  3. 作用域插槽用于子组件提供数据,父组件决定如何渲染。例如 Table 提供 row,父组件决定某列显示按钮还是标签。
  4. Vue 2 中常见 slot、slot-scope 写法;Vue 2.6+ 和 Vue 3 推荐统一使用 v-slot 或 # 简写。
  5. 插槽适合开放结构扩展点,不适合所有定制都用插槽。简单文本、状态和开关仍然应该优先用 props。

题目解析

插槽解决的是“内容由谁决定”的问题。子组件负责布局框架,父组件负责填内容。

作用域插槽的方向容易说错:数据来自子组件,模板写在父组件。

组件库里插槽越多,灵活性越高,但约束也越弱。核心区域可以给插槽,稳定配置仍应使用 props。

代码示例

列表组件把 item 交给父组件,父组件通过作用域插槽决定每一项怎么展示。

Vue
<!-- UserList.vue -->
<script setup lang="ts">
defineProps<{
  users: Array<{ id: number; name: string; role: string }>
}>()
</script>

<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      <slot name="item" :user="user">
        {{ user.name }}
      </slot>
    </li>
  </ul>
</template>
Vue
<UserList :users="users">
  <template #item="{ user }">
    <strong>{{ user.name }}</strong>
    <span>{{ user.role }}</span>
  </template>
</UserList>

常见误区

  • 把作用域插槽理解成父组件把数据传给子组件。实际是子组件把数据暴露给父组件模板。
  • 组件接口能用 props 表达,却滥用插槽,导致调用方结构不统一。
  • Vue 2 老写法和 Vue 3 v-slot 写法混在一起,迁移时模板可读性变差。

作者信息