ThemeSettings 导航模式卡片与样式细化
概述
主题设置面板搭好抽屉与表单骨架后,真正的产品化分水岭是「导航模式」这类配置项。它不再是普通开关,而是直接影响后台布局形态的布局级选择,因此更适合用可视化缩略卡片表达。本节把导航模式从文本配置升级为卡片选择器,并处理卡片作为状态块的视觉层级、FormItem 纵向化、缩略图用色块模拟、共享样式抽象与圆角裁切,最终完成 ThemeSettings 的样式面板阶段。
学习目标
- 识别导航模式等「布局级配置」,用可视化卡片而非文本下拉表达布局差异
- 用
Tooltip + 卡片组合降低用户理解成本,并让卡片具备默认 / hover / active 视觉层级 - 对该 FormItem 改用纵向布局,避免模式卡片与横向 label 挤在一起
- 用普通色块与绝对定位模拟布局缩略图,避免引入额外绘图资源
- 把重复卡片样式抽成共享类,并注意父容器
relative + overflow-hidden的圆角裁切
一、导航模式:从文本配置升级为可视化卡片
ThemeSettings 里大多数配置(Logo 显示、菜单宽度、主题色、暗黑模式)仍是挂在统一 form 上的标准表单项,复杂度主要在组织而非控件本身。但导航模式不同——它切换的是左侧菜单、顶部菜单或混合布局的整体形态,属于前一节说的「布局级配置」。如果只用普通下拉框或单选按钮,用户很难直观理解 sidebar / top / mix / dual-sidebar 的差异,而可视化小卡片能让布局区别一眼可见。课程口述里出现过 mixTop、mixedBar 这类阶段性命名,项目里更推荐最终收口成与布局系统一致的稳定枚举。
二、卡片即状态块:视觉层级与 FormItem 纵向化
导航模式卡片不是普通按钮,而是「代表布局预览的状态块」:交互重点不在文字,而在当前是否选中、预览图是否清晰、hover / active 边框是否明显。它至少需要四层视觉状态:默认背景、hover 反馈、active 边框、必要时轻微阴影或浅边框。
这类卡片接入后,FormItem 的内部布局要从「左 label 右控件」的横向结构改成「label 在上、卡片在下」的纵向结构。继续沿用普通表单项横向布局,四个卡片会非常拥挤、不利于展示。规律是:开关、颜色、滑块适合横向表单项,卡片选择、模式预览适合纵向表单项。
三、缩略图用色块模拟而非绘制
课程实现四种导航模式缩略图时,没有上 SVG 或复杂图形,而是继续用 div + 背景色块 + 绝对定位 + 宽高比例来模拟侧边栏、顶部栏、内容区的关系:
<div class="mode-item">
<div class="absolute left-0 top-0 z-30 h-full w-1/4 bg-gray-900" />
<div class="absolute left-1/4 top-0 z-10 h-full w-3/4 bg-white" />
</div>深色块表达菜单、浅色块表达内容区,通过比例关系就能模拟「左侧菜单 + 右侧内容」的预览。实现 mixTop 可加顶部横条再补左侧窄菜单,top 把深色块放顶部横向,dual-sidebar 拆成两列深浅不同的左侧区域——不依赖额外图标素材,改颜色比例也方便。配合 el-tooltip 在 hover 时给出模式说明文字,是比纯文本单选更自然的交互:默认界面保持简洁,移上去再补语义。
四、共享样式抽象与圆角裁切
四个模式块的外层样式(圆角、背景、边框、尺寸)几乎一样,应尽早抽成共享类(如 .mode-item)统一复用,避免同一视觉卡片重复写多遍、后续改尺寸颜色时到处改。课程里把卡片从偏大的正方形收成更扁的矩形,更接近真实后台布局缩略图比例。
圆角能否生效有个典型细节:内部子元素用了 absolute 铺满,若父元素有圆角却不隐藏溢出,内部色块会把圆角「冲破」。规律几乎是固定的——父级有圆角、子级又要绝对定位铺满时,overflow-hidden 是标配:
.mode-item {
@apply relative overflow-hidden rounded bg-gray-100 shadow-sm;
@apply w-12 h-8 cursor-pointer border border-gray-200;
}
.mode-item.active {
@apply border-2 border-blue-900;
}五、样式面板收尾与联动预告
这一节让 ThemeSettings 的气质发生了变化:从「能弹出、能显示几个控件」变成「有结构层次、有模式卡片、有 hover 说明、有 active 反馈」,更接近真实后台产品的设置面板。但样式也不是终点——面板里的配置值如何真正驱动外层 DefaultLayout 才是下一阶段的重量级难点:
navMode要切换菜单结构menuWidth要影响侧边栏宽度showLogo要影响布局展示- 主题色、菜单背景要与 Header / 菜单样式同步
到本节为止,ThemeSettings 已具备「可展示、可选择、可输入」的样式面板能力,下一步进入配置联动阶段。
六、数据驱动渲染:抽出配置数组
四种模式的卡片结构高度一致,逐个手写 mode-item + tooltip 会带来大量重复 DOM,且新增模式要改模板。更好的做法是把模式定义抽成配置数组,再用 v-for 渲染:
const navModeOptions = [
{ value: "sidebar", label: "左侧菜单", desc: "经典侧边栏布局" },
{ value: "top", label: "顶部菜单", desc: "顶部横向导航" },
{ value: "mixTop", label: "混合顶部", desc: "顶部一级 + 左侧二级" },
{ value: "mixedBar", label: "混合栏", desc: "双列侧边菜单" }
]<div class="flex gap-3">
<el-tooltip
v-for="item in navModeOptions"
:key="item.value"
:content="item.desc"
placement="top"
>
<div
class="mode-item"
:class="{ active: form.navMode === item.value }"
@click="form.navMode = item.value"
>
<span class="mode-thumb" :data-mode="item.value" />
</div>
</el-tooltip>
</div>数组化之后,选中态判断、Tooltip 文案、缩略图类型都来自同一份数据,维护和扩展成本显著下降。
七、navMode 枚举与布局结构映射
每个 navMode 值并不是孤立字符串,它背后对应着布局层的真实结构变化。提前把它们映射清楚,下一节的配置回传才不会「改了值却不知道布局怎么动」:
| navMode | 菜单位置 | 头部内容 | 内容区 |
|---|---|---|---|
sidebar | 左侧完整菜单 | 仅工具区 | 右侧自适应 |
top | 收起,菜单上移头部 | 横向菜单 + 工具区 | 下方整块 |
mixTop | 顶部一级 + 左侧二级 | 顶部一级导航 | 左侧二级 + 内容 |
mixedBar | 双列侧边(一级窄、二级宽) | 工具区 | 右侧内容 |
这一映射关系,也是后续 DefaultLayout 根据 navMode 切换组件结构、决定 Sidebar 与 Header 各自渲染内容的依据。
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 导航模式用文字单选看不懂区别 | 抽象模式缺直观表达 | 用缩略卡片 + Tooltip 让布局差异可视化 |
| 模式卡片与 label 挤在一行 | 沿用普通表单项横向布局 | 该 FormItem 改纵向,label 在上卡片在下 |
| 卡片圆角不生效 | 内部绝对定位色块溢出父容器 | 父容器同时设 relative 与 overflow-hidden |
| 四种卡片样式越来越难改 | 没抽共享类 | 统一 .mode-item 等类复用 |
| 正方形卡片不像布局缩略图 | 高宽比例过大显「厚」 | 收成扁矩形,补轻微阴影浅边框 |
| DOM 结构越写越重复 | 直接复制卡片与 Tooltip | 抽 navModeOptions 配置数组配合 v-for |