动态插槽名用:name="variable"绑定,父组件用v-slot:[variable];插槽存在性通过$slots.name或slots.name?.()判断,二者组合实现按需分发内容。

Vue插槽的动态插槽名和插槽存在性判断,是构建高复用、可配置 UI 组件(比如通用卡片、布局容器、表单域)的关键能力。它们让组件能根据运行时条件决定“往哪塞内容”以及“要不要塞”,而不是写死插槽名或盲目渲染空位。
动态插槽名:用变量控制插槽出口
当插槽名称需要由 prop、响应式数据或计算结果决定时,不能写死 <slot name="header">,而要用方括号语法绑定 name 属性:
- 子组件中定义:
<slot :name="currentSection"></slot>,其中currentSection是一个响应式字符串,比如ref('sidebar')或computed(() => isMobile.value ? 'mobile-header' : 'desktop-header') - 父组件使用时,对应使用动态
v-slot:<template #[currentSection]>...</template>;注意必须用方括号语法,v-slot:header这种字面量写法不支持变量 - 常见场景:多语言界面切换头部区域、主题模式下切换插槽命名、表单字段根据类型动态挂载 label / control / error 插槽
插槽存在性判断:避免渲染空插槽或报错
直接访问 $slots.xxx 可能为 undefined,尤其在具名插槽未被父组件提供时。Vue 提供了安全判断方式:
- 推荐写法:
v-if="$slots.header"或if (this.$slots.header)(Options API),在 Vue 3 Composition API 中用slots.header?.()判断是否可调用(因为插槽函数本身是函数) - 更严谨的做法是结合插槽内容非空判断:
if (slots.header && slots.header().length),防止传入空文本节点 - 典型用途:布局组件中只在提供
footer插槽时才渲染底部边框;表格组件中仅当empty插槽存在时才覆盖默认空状态提示
组合使用:动态名 + 存在性 = 真正的弹性
把两者结合,就能实现“按需加载、按名分发”的智能内容路由:
立即学习“前端免费学习笔记(深入)”;
- 子组件中:
<slot :name="activeTab" v-if="$slots[activeTab]"></slot> - 父组件中:
<template #[tabName]>{{ tabContent }}</template>,配合v-for动态生成多个具名插槽 - 注意事项:动态插槽名必须是合法标识符(不能含空格、特殊符号),建议统一做
kebab-case校验或转换;同时避免高频变更插槽名导致不必要的重渲染
避坑提醒
几个容易忽略但影响稳定性的细节:
-
$slots在setup()中不可直接解构,应保留slots参数并始终通过它访问,否则响应性会丢失 - 动态插槽名不支持表达式嵌套,如
:name="`item-${index}-content`"可以,但:name="getSlotName(item) + '-body'"需确保函数纯且无副作用 - 服务端渲染(SSR)中,插槽函数在
serverPrefetch阶段不可用,存在性判断需放在onMounted或模板v-if中


















