一、背景:组件“够用”≠“好用”,更不是“可扩展”
广告平台最早使用的是 Naive UI + 本地封装组件,但存在以下问题:
- 同类表单页面重复堆砌,体验不统一
- 页面间字段格式/布局风格差异大
- 样式、命名、功能缺少规范,维护困难
因此我主导建设了一个“轻量级、可扩展、跨项目复用”的组件库系统。
二、组件库设计目标:三统一 + 三开放
三统一:
- 样式统一(UI视觉风格)
- 行为统一(交互体验)
- 代码统一(props、emit、slot 命名)
三开放:
- 开放配置(支持 props 驱动)
- 开放插槽(适配复杂场景)
- 开放样式(暴露 class/token)
三、核心组件分层结构
@ad-ui-lib
│
├── base/ # 基础组件(Button, Input)
├── biz/ # 业务组件(SearchForm, TableForm)
├── layout/ # Layout 相关组件(Header, TabView)
├── token/ # 样式主题变量
└── index.ts # 导出入口
四、基础组件设计原则
以 AdButton 为例:
<template>
<n-button :type="type" :loading="loading">
<slot />
</n-button>
</template>
<script setup>
defineProps({ type: String, loading: Boolean })
</script>
设计原则:
- props 对标原生组件,保持直觉
- 统一类名(如
ad-btn-primary) - 默认提供 loading、权限控制逻辑扩展点
五、业务组件:可配置 + 可组合
以 SearchTable.vue 为例:集成查询条件 + 表格展示 + 分页控制
<SearchTable :columns="columns" :api="fetchList" :formSchema="searchSchema" />
- 查询区域 schema 驱动生成(支持插槽)
- 表格 columns 支持 render + dict 映射
- 支持 props 控制分页、loading、刷新按钮
六、样式体系设计:token + class 解耦
:root {
--ad-color-primary: #1890ff;
--ad-radius: 8px;
}
组件使用:
.ad-btn-primary {
background-color: var(--ad-color-primary);
border-radius: var(--ad-radius);
}
支持暗黑模式切换、项目级 token override
七、开发体验优化
- 使用
unplugin-vue-components支持按需自动引入 - 内置文档 demo 页面:组件预览 + props 表
- Vitest 单元测试覆盖率 90% 以上
八、跨项目复用机制
- 使用
pnpm workspace管理依赖 - 打包为 npm 包:
@ad/ui-lib - 提供 umd / esm / cjs 三种格式输出
- 支持不同项目按需使用或整体引入
九、版本管理与发布策略
- 每次变更自动生成 changelog
- 多版本并行维护(支持锁定旧版本)
- 使用 semantic-release 自动发布
npm run build && npm publish
十、总结
一个好用的组件库,不是“造很多轮子”,而是让团队写更少的代码、更一致的页面、更稳定的产品。
我主导的组件体系已经落地多个项目,显著提升了研发效率、用户体验一致性与团队协作流畅度。