升级云原生控制台体验:一线项目里我是如何用 DevUI 把表格、表单和主题“拉满”的
- DevUI 官网:https://devui.design/home
- MateChat GitCode 仓库:https://gitcode.com/DevCloudFE/MateChat
- MateChat 官网:https://matechat.gitcode.com

1. 为什么最后选了 DevUI
这篇不是官方介绍,而是我在一个云原生控制台项目里,真正在代码里把 DevUI 用顺手之后的复盘。
项目形态比较典型:
- 场景:多租户云原生控制台,涵盖集群管理、应用发布、日志与告警等功能。
- 约束:交付时间紧,交互需求又复杂,尤其是表格与表单特别多。
- 诉求:
- 需要一套稳定的企业级 UI 组件;
- 要能方便做品牌皮肤和暗黑模式;
- 要适合长列表、高并发操作的 B 端场景。
我们最开始也看了几套 UI 库,最后选 DevUI 的核心原因有三个:
- 组件针对 B 端场景打磨得比较细,表格、表单、弹窗实战体验比通用 UI 库更“稳”;
- 文档和示例对工程实践比较友好,很多是直接可复制的业务组合方案;
- 天然更贴近云管平台、控制台这类典型场景,上手不需要太多“自行二次封装”。
下面几节只聊我真用过、踩过坑的部分,不做概念性介绍。
2. 表格组件深入实践:从“能用”到“好用”
2.1 列配置:不要在模板里写死
最开始我们是直接在模板里写 column,这样改一次列顺序就要动模板。后来我们统一改成“列配置 + 渲染函数”的写法,让表格列可配置且更好维护。
下面是简化版示例(Vue + TypeScript 思路):
interface ColumnConfig {
field: string;
header: string;
width?: string;
sortable?: boolean;
showOverflow?: boolean;
formatter?: (row: any) => string;
}
const clusterColumns: ColumnConfig[] = [
{
field: 'name',
header: '集群名称',
width: '220px',
showOverflow: true,
},
{
field: 'status',
header: '状态',
width: '120px',
formatter: (row) => mapStatusLabel(row.status),
},
{
field: 'nodeCount',
header: '节点数',
width: '120px',
sortable: true,
},
];
在模板里只做一个 v-for 渲染,真正的“业务规则”都放在配置里:
<d-data-table
[dataSource]="clusterList"
[pagination]="paginationConfig"
>
<ng-template dHead let-columns>
<tr>
<th *ngFor="let col of clusterColumns">{{ col.header }}</th>
</tr>
</ng-template>
<ng-template dBody let-row let-columns="columns">
<tr>
<td *ngFor="let col of clusterColumns">
{{ col.formatter ? col.formatter(row) : row[col.field] }}
</td>
</tr>
</ng-template>
</d-data-table>
这种写法带来的直接收益:
- 产品要加列 / 调整顺序:只动配置数组;
- 不同租户、不同角色看到的列不一样:在配置层加一层过滤即可;
- 方便后面做“用户可自定义列显示”的功能。
2.2 大数据量场景:分页 + 虚拟滚动的取舍
控制台里有几个列表数据量非常大。我们试过两种方案:
- 纯分页:后端分页,每次请求 50 条,前端普通表格;
- 分页 + 虚拟滚动:一次多拉一点数据,配合 DevUI 的虚拟滚动方案。
实际用下来,我们的经验是:优先保证可观测性,再考虑极致性能。
- 运维同事更在乎筛选和排序的准确性,其次才是滚动是否完全丝滑;
- 只要分页和条件响应够快,纯分页在大多数场景就够用了。
因此,除了一个“审计日志”场景用了虚拟滚动,其它列表都坚持简单分页 + 服务器过滤,省下了很多不必要的调优时间。
2.3 操作列设计:别把所有按钮都塞进一列
我在第一版设计里犯过一个错:把“编辑、下线、扩容、缩容、查看 YAML”全塞进操作列,结果宽度根本放不下。
后来改成三层:
- 表格操作列只保留 最核心的两三个动作;
- 其余操作收进一个
更多下拉; - 复杂动作(比如 YAML 查看)单独跳转到详情页处理。
视觉上更干净,权限控制也更好做。DevUI 自带的按钮、下拉菜单组件就足够好用,不需要自己花时间造轮子。
3. 表单与弹窗:把业务流程拆进组件里
3.1 表单分段:长表单一定要拆
创建集群的表单一开始非常长,字段接近 30 个。我们用 DevUI 的步骤条 + 多段表单做了拆分:
- 基本信息(名称、区域、K8s 版本)
- 资源规格(节点规格、数量、计费)
- 网络与安全(VPC、子网、安全组)
每一段用一个独立的表单组件承载,最后统一汇总提交。大概结构:
<d-steps [activeIndex]="activeStep">
<d-step title="基本信息"></d-step>
<d-step title="资源规格"></d-step>
<d-step title="网络与安全"></d-step>
</d-steps>
<app-basic-form
*ngIf="activeStep === 0"
(validChange)="onValidChange(0, $event)"
></app-basic-form>
<app-spec-form
*ngIf="activeStep === 1"
(validChange)="onValidChange(1, $event)"
></app-spec-form>
这样拆完一个明显感受:
- 校验逻辑更清晰,每个子表单只关注自己的校验规则;
- 新人接手代码更容易看懂,也更利于后面的扩展。
3.2 弹窗复用:不要在每个页面“现写一套”
我们项目里最常见的弹窗是:二次确认、单字段编辑、小范围批量操作。最初每个页面都自己写 d-dialog,到后面维护成了灾难。
最后我们沉淀出了两个基础弹窗组件:
ConfirmDialog:标题 + 内容 + 左右两个按钮;FormDialog:内嵌一个简化表单,支持动态配置字段。
简化版伪代码:
openConfirm(title: string, content: string): Observable<boolean> {
const ref = this.dialogService.open(ConfirmDialogComponent, {
data: { title, content },
backdropCloseable: false,
});
return ref.afterClosed();
}
实践下来最直观的好处是:
- 样式一致,体验统一;
- 后面接入国际化时,只需要改这一处的文案策略。
4. 主题与暗黑模式:真实项目里的品牌适配套路
4.1 品牌色抽象:别在组件里写死颜色
我们有集团统一视觉规范,品牌主色、辅色、状态色都已经给定。最开始同事图省事,在某些页面里直接写 #0052d9 这种色值,结果换主题时非常痛苦。
后面我们统一做了两件事:
- 所有颜色都抽象成变量(Less / SCSS 变量均可);
- 页面里只使用“语义化变量”,比如
--color-brand-primary。
配合 DevUI 的主题定制能力,切换到暗黑模式时,只需要替换变量值即可。
4.2 暗黑模式的几个细节
暗黑模式不是简单地把背景变黑,我们在实践中重点处理了三点:
- 表格边界与分割线:如果对比度不够,长表格在暗色背景下会非常难读;
- 告警色:原来偏亮的黄色、红色在暗色背景下要适当降低饱和度;
- 悬浮层(弹窗、下拉):要同时考虑亮色 / 暗色下的阴影与层级关系。
我们给自己定了一个原则:
先保证可读性,其次再追求“暗黑质感”。
为了验证效果,我们让几个真正每天盯着控制台的运维同事试用一周,再根据反馈细调颜色和字号,而不是凭感觉拍脑袋改样式。
5. 云原生控制台落地复盘:从界面到交互的一次完整改造
结合前面的几点,我们在一次较大的版本升级中,对“集群管理”模块做了一个比较彻底的 UI 改造,大致过程是:
- 先梳理核心操作路径:
- 查看集群健康 → 查看异常详情 → 进入日志与告警;
- 扩容 / 缩容 → 查看任务进度 → 审计日志。
- 再围绕操作路径调整布局与组件:
- 首页用 DevUI 的卡片 + 表格组合,一屏内给出“关键指标 + 列表”;
- 将操作入口集中到右侧固定区域,减少用户视线来回移动。
- 最后做主题与暗黑兼容:
- 优先保证最常用的两个页面(集群列表、集群详情)在暗黑模式下的可读性;
- 其它页面先用通用样式兜底,逐步细化。
这次改造中,一个明显的感受是:
- 如果没有 DevUI 的成熟组件,我们很多时间会浪费在“基础交互”上;
- 现在更多精力可以放在业务流程与交互设计本身,而不是基础轮子。
6. 常见坑与排查经验
这里列几个我真踩过的坑,避免大家重复:
- 表格自适应问题:
- 一开始所有列都不设宽度,结果在窄屏下列宽被压得非常难看;
- 建议对关键列设置最小宽度,对次要列允许自动收缩。
- 弹窗嵌套弹窗:
- 我们有一处“在详情页弹窗里再开一个确认弹窗”,结果焦点和滚动都乱了;
- 后来全部改成“弹窗里只允许开消息提示”,真正的二次确认回到页面层做。
- 主题切换状态同步:
- 如果主题依赖全局状态,一定记得在路由切换时同步应用;
- 我们后来是把主题持久化到 localStorage,并在 App 初始化时主动读取。
7. 最后建议
如果你刚好在做云原生控制台、企业级 B 端管理平台,我会比较直接地建议:
- 先花半天把 DevUI 的表格、表单、弹窗几个核心组件过一遍;
- 用一两个真实页面练手,不要从 demo 开始,而是从真实需求切入;
- 提前规划好主题和暗黑模式的策略,别等业务上线后再回头补。
更多推荐

所有评论(0)