用插槽实现移动端Tab栏图标切换的核心是通过具名插槽(icon/active-icon)分离未选中与选中图标,配合v-model控制激活态,由TabItem用v-if动态渲染,TabBar派发update:modelValue事件,父组件灵活传入SVG、iconfont等响应式图标内容。

用插槽(slot)实现移动端 Tab 栏的图标切换,核心在于把图标部分抽离为可替换内容,让父组件灵活传入不同状态下的图标(比如未选中、选中),同时配合 v-model 或事件控制激活态。不依赖第三方 UI 库,纯 Vue 3 + Composition API 即可完成。
一、Tab 栏基础结构与插槽设计
Tab 栏本质是一个横向滚动容器 + 多个可点击项。每个 tab 需要支持:文字 + 图标(默认态/激活态)+ 状态反馈。用具名插槽区分图标区域:
- default 插槽:放 tab 文字(如“首页”)
- icon 插槽:放图标内容,内部根据 is-active 动态决定渲染哪个图标
- active-icon 插槽(可选):专门传入选中态图标,更清晰分离逻辑
二、子组件封装:TabItem 与 TabBar
TabItem 负责单个标签,接收 index、title、isActive 等 props;TabBar 负责管理激活索引、横向滚动、事件派发。关键点:
- TabItem 内部用
<slot name="icon"></slot>渲染图标区域 - 通过
v-if="isActive"和v-else控制 icon / active-icon 插槽显示 - TabBar 用
defineEmits(['update:modelValue'])支持 v-model 绑定 - 点击时触发 emit('update:modelValue', index),由父组件响应更新
三、父组件中使用插槽自定义图标
真正体现灵活性的地方:你可以用 SVG 内联、iconfont、img 标签,甚至动态 import 的组件。例如:
- 未选中用灰色 SVG,选中用蓝色带描边 SVG
- 用
<template #icon>...</template>和<template #active-icon>...</template>分别传入 - 结合
computed或ref做图标缓存或尺寸适配(如移动端统一 24px) - 图标可绑定 class 或 style 实现颜色/大小响应式变化
四、状态联动与视觉反馈优化
仅切换图标不够,还需增强体验:
- 添加 CSS 过渡:对 icon 容器加
transition: all 0.2s - 选中态文字加粗或变色,和图标风格统一
- TabBar 底部加指示条(indicator),用
transform: translateX()模拟滑动效果 - 移动端注意 touch-action: manipulation 防止延迟,禁用长按菜单
不复杂但容易忽略:插槽内容在子组件作用域内不自动响应 isActive 变化,需确保父组件传入的插槽内容本身是响应式的,或在 TabItem 内用 v-if 显式控制渲染分支。

















