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