Vue动态组件切换通过实现,配合可保持状态;默认插槽接收父组件内容并支持后备;具名插槽按name分发内容;作用域插槽允许子组件向父组件传递数据;动态插槽名与v-if可实现条件化内容分发。

一、动态组件切换与状态保持
当需要在同一个挂载点按条件切换不同组件时,Vue 提供了 <component> 内置元素配合 :is 属性实现动态渲染。该机制避免重复创建/销毁实例,提升响应效率。
1、在模板中使用 <component> 标签,并绑定 :is 动态值:
<component :is="currentComponentName"></component>
2、在 data 或 reactive 中定义 currentComponentName 初始值,例如 'UserList' 或 'UserProfile'
3、通过事件(如按钮点击)修改 currentComponentName 值,触发组件切换
立即学习“前端免费学习笔记(深入)”;
4、为保留已切换组件的状态(如表单输入、滚动位置),将 <component> 包裹在 <keep-alive> 内:
<keep-alive><component :is="currentComponentName"></component></keep-alive>
5、若仅需缓存特定组件,使用 include 属性限定:
<keep-alive include="UserList,UserProfile"><component :is="currentComponentName"></component></keep-alive>
二、默认插槽的内容注入与后备处理
默认插槽是子组件中未命名的 <slot> 占位符,用于接收父组件直接写在标签体内的全部内容。它支持任意合法模板结构,并可设置后备内容以应对空传场景。
1、在子组件模板中声明无 name 属性的 <slot>:
<div class="card"><slot>默认卡片内容</slot></div>
2、父组件使用时,在开始与结束标签之间插入任意内容:
<Card><h2>欢迎页</h2><p>这是自定义主体</p></Card>
3、若父组件未提供内容,则子组件中 <slot> 标签内部的文本(如“默认卡片内容”)将被渲染
4、后备内容仅在插槽内容为空时生效;若父组件传入空白标签(如 <div></div>),仍视为有内容,后备内容不显示
三、具名插槽的区域化内容分发
具名插槽通过 name 属性标识多个独立出口,使父组件能将不同结构的内容精准投递至子组件预设的逻辑区域(如 header、footer、aside),增强布局控制力。
1、在子组件中为每个插槽添加唯一 name:
<header><slot name="header">默认标题</slot></header>
<main><slot name="default">默认正文</slot></main>
<footer><slot name="footer">默认页脚</slot></footer>
2、父组件使用 v-slot 指令(或简写 #)指定目标插槽:
<Layout>
<template #header><h1>主面板</h1></template>
<p>此段落进入默认插槽</p>
<template #footer><small>© 2026</small></template>
</Layout>
3、v-slot:default 可省略为直接写在组件标签内,但显式命名有利于多人协作与可读性
4、未匹配 name 的内容不会被丢弃,而是统一归入 name="default" 插槽(若存在)
四、作用域插槽实现子组件数据反向传递
作用域插槽允许子组件将自身内部的数据(如列表项、状态标志、方法)通过 v-bind 绑定到 <slot> 上,使父组件能在插槽内容中访问并定制渲染逻辑,打破单向数据流限制。
1、子组件在 <slot> 标签上使用 v-bind 传递数据:
<li v-for="item in items" :key="item.id">
<slot :item="item" :index="loop.index" :isActive="item.active"></slot>
</li>
2、父组件使用 v-slot 解构接收参数:
<ItemList>
<template v-slot="{ item, index, isActive }">
<span class="badge" :class="{ active: isActive }">{{ index + 1 }}. {{ item.title }}</span>
</template>
</ItemList>
3、v-slot 可带参数名,支持解构赋值,亦可使用完整对象形式 v-slot="scope"
4、插槽内容中的表达式运行在父组件作用域,因此可自由结合父组件 data、methods 和 computed 使用
五、动态插槽名与条件插槽控制
动态插槽名允许运行时计算插槽名称,结合 v-if/v-else 控制插槽是否启用,从而实现更灵活的内容分发策略,适用于多主题、多角色或配置驱动型组件。
1、在子组件中使用动态 name 属性:
<slot :name="layoutMode === 'compact' ? 'compact-header' : 'full-header'"></slot>
2、父组件根据条件提供对应插槽:
<Dashboard>
<template #compact-header><h3>紧凑模式</h3></template>
<template #full-header><h2>完整模式</h2></template>
</Dashboard>
3、使用 v-if 控制插槽是否渲染:
<template v-if="showActions"><template #actions><button>保存</button></template></template>
4、动态插槽名必须为字符串类型,不可为 undefined 或 null,否则插槽无法匹配


















