Vue中具名作用域插槽需子组件用<slot name="xxx" :prop="data">暴露,父组件用v-slot:xxx="{ prop }"在<template>内解构接收,名称必须严格匹配,且禁用旧语法。

Vue 单文件组件中编写具名插槽与作用域插槽,关键在于子组件用 <slot name="xxx" :prop="data"> 暴露带数据的命名出口,父组件用 v-slot:xxx="{ prop }" 解构接收——二者必须严格对应,且 v-slot 只能写在 <template> 标签上。
子组件:定义具名 + 作用域插槽出口
在 <template> 中,为不同区域设置 name,并通过绑定属性(如 :item、:index)传递数据:
-
头部区域:
<slot name="header" :title="cardTitle">默认标题</slot> -
操作区域:
<slot name="actions" :item="user" :disabled="user.locked"><button>删除</button></slot> -
默认插槽也可带作用域:
<slot :user="user" :role="user.role">{{ user.name }}</slot>
父组件:用 v-slot 接收并解构使用
调用时,每个 v-slot:xxx 必须包裹在独立的 <template> 内,解构名需与子组件传入的属性名一致:
-
具名+作用域组合:
<template #header="{ title }"><h2>{{ title.toUpperCase() }}</h2></template> -
多参数解构:
<template #actions="{ item, disabled }"><button :disabled="disabled" @click="remove(item)">移除</button></template> -
默认插槽带作用域:
<template v-slot="{ user, role }"><span class="tag">{{ role }}</span> {{ user.name }}</template>
常见错误避坑点
实际编码中容易卡在这几个地方:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
立即学习“前端免费学习笔记(深入)”;
- 把
v-slot:header写在普通标签上(比如直接写在<div>上)——必须用<template> - 子组件传
:info="item",父组件却写v-slot:header="{ item }"——解构名要完全匹配 - 混用旧语法,比如写
slot="header"或slot-scope——Vue 3 已废弃,只认v-slot或简写# - 在一个
<template>上同时写#header和v-slot:scope——语法冲突,会报错
一个可运行的小例子
子组件 UserCard.vue:
<div class="card">
<header><slot name="header" :title="user.name">{{ user.name }}</slot></header>
<main><slot :user="user">{{ user.email }}</slot></main>
<footer><slot name="footer" :id="user.id"><button @click="$emit('delete', user.id)">删除</button></slot></footer>
</div>
</template>
<script setup>
const props = defineProps({ user: Object })
</script>
父组件中调用:
<UserCard v-for="u in users" :key="u.id" :user="u"><template #header="{ title }"><h3 style="color:#2c3e50">? {{ title }}</h3></template>
<template v-slot="{ user }"><p>? {{ user.email }}</p></template>
<template #footer="{ id }"><button @click="archive(id)">归档</button></template>
</UserCard>

















