• 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 改造,大致过程是:

  1. 先梳理核心操作路径:
    • 查看集群健康 → 查看异常详情 → 进入日志与告警;
    • 扩容 / 缩容 → 查看任务进度 → 审计日志。
  2. 再围绕操作路径调整布局与组件:
    • 首页用 DevUI 的卡片 + 表格组合,一屏内给出“关键指标 + 列表”;
    • 将操作入口集中到右侧固定区域,减少用户视线来回移动。
  3. 最后做主题与暗黑兼容:
    • 优先保证最常用的两个页面(集群列表、集群详情)在暗黑模式下的可读性;
    • 其它页面先用通用样式兜底,逐步细化。

这次改造中,一个明显的感受是:

  • 如果没有 DevUI 的成熟组件,我们很多时间会浪费在“基础交互”上;
  • 现在更多精力可以放在业务流程与交互设计本身,而不是基础轮子。

6. 常见坑与排查经验

这里列几个我真踩过的坑,避免大家重复:

  • 表格自适应问题:
    • 一开始所有列都不设宽度,结果在窄屏下列宽被压得非常难看;
    • 建议对关键列设置最小宽度,对次要列允许自动收缩。
  • 弹窗嵌套弹窗:
    • 我们有一处“在详情页弹窗里再开一个确认弹窗”,结果焦点和滚动都乱了;
    • 后来全部改成“弹窗里只允许开消息提示”,真正的二次确认回到页面层做。
  • 主题切换状态同步:
    • 如果主题依赖全局状态,一定记得在路由切换时同步应用;
    • 我们后来是把主题持久化到 localStorage,并在 App 初始化时主动读取。

7. 最后建议

如果你刚好在做云原生控制台、企业级 B 端管理平台,我会比较直接地建议:

  • 先花半天把 DevUI 的表格、表单、弹窗几个核心组件过一遍;
  • 用一两个真实页面练手,不要从 demo 开始,而是从真实需求切入;
  • 提前规划好主题和暗黑模式的策略,别等业务上线后再回头补。

更多推荐