@robot-admin/naive-ui-components
September 1, 2026 · View on GitHub
@robot-admin/naive-ui-components
基于 Naive UI 的 Vue 3 企业级组件库
从 Robot Admin 中提炼的 51 个高质量业务组件,支持全量注册、按需导入(Tree-Shaking)和子路径独立导入。
📦 安装
bun add @robot-admin/naive-ui-components
必需的对等依赖:
bun add vue@^3.5.0 naive-ui@^2.35.0
🚀 快速开始
全局注册
import { createApp } from 'vue'
import NaiveUIComponents from '@robot-admin/naive-ui-components'
import '@robot-admin/naive-ui-components/style.css'
const app = createApp(App)
app.use(NaiveUIComponents)
app.mount('#app')
按需导入(主入口 Tree-Shaking)
<script setup lang="ts">
import { C_Icon, C_Table, C_Form } from '@robot-admin/naive-ui-components'
import '@robot-admin/naive-ui-components/style.css'
</script>
子路径独立导入(推荐,最小打包体积)
每个组件都提供独立的子路径入口,仅加载目标组件的代码和类型:
<script setup lang="ts">
import { C_Form } from '@robot-admin/naive-ui-components/C_Form'
import { C_Table } from '@robot-admin/naive-ui-components/C_Table'
import { C_Icon } from '@robot-admin/naive-ui-components/C_Icon'
import { createMenuOptions } from '@robot-admin/naive-ui-components/C_Menu'
import '@robot-admin/naive-ui-components/style.css'
</script>
子路径导入提供完整的 TypeScript 类型支持(
.d.ts),IDE 可自动补全 props / emits / slots。组件相关工具函数(如createMenuOptions)也从对应组件子路径导出,避免为了单个工具加载组件库根入口。
Composables 单独使用
import {
useTableManager,
useFormState,
usePlayerCore,
} from '@robot-admin/naive-ui-components'
自动按需导入(推荐)
Resolver 默认从组件子路径加载,避免只使用少量组件时把整个组件库及重型运行依赖带入首屏:
import Components from 'unplugin-vue-components/vite'
import { RobotNaiveUiResolver } from '@robot-admin/naive-ui-components/resolver'
Components({
resolvers: [RobotNaiveUiResolver({ importStyle: true })],
})
importStyle: true(等价于 'full')保持原有完整样式行为。只使用 C_Form/C_Table 基础字段、不使用内置富文本编辑器时,可设置 importStyle: 'base',避免带入编辑器样式;其他组件会安全回退到标准样式入口。如需兼容旧项目的主入口导入,可显式设置 importOnDemand: false。
也可以手动选择样式层级:
import '@robot-admin/naive-ui-components/C_Form/base.css'
import '@robot-admin/naive-ui-components/C_Table/base.css'
// 完整模式也可显式使用 C_Form/full.css、C_Table/full.css
C_Form / C_Table 推荐用法
推荐使用类型助手和绑定助手:业务模型只声明一次,字段路径、字段值、列 key、保存回调和实例方法即可保持同一套类型推导。字段支持 profile.name、contacts.0.email 这类嵌套路径。
<script setup lang="ts">
import {
C_Form,
defineFormConfig,
defineFormOptions,
useCForm,
} from '@robot-admin/naive-ui-components/C_Form'
interface UserForm {
name: string
departmentId: number | null
profile: { email: string }
}
const fields = defineFormOptions<UserForm>([
{
type: 'input',
prop: 'name',
label: '名称',
required: true,
},
{
type: 'select',
prop: 'departmentId',
label: '部门',
asyncOptions: async (_model, context) =>
fetch('/api/departments', { signal: context?.signal }).then(response =>
response.json()
),
},
{ type: 'input', prop: 'profile.email', label: '邮箱' },
])
const config = defineFormConfig<UserForm>({
mode: 'edit',
validateOnChange: true,
onSubmit: async ({ model: validatedModel }) => save(validatedModel),
onError: (error, context) => reportError(error, context),
})
const { model, formRef, bindings } = useCForm<UserForm>({
initialValues: {
name: '',
departmentId: null,
profile: { email: '' },
},
options: fields,
config,
})
</script>
<template>
<C_Form
ref="formRef"
v-bind="bindings"
/>
</template>
远程表格推荐交给 useTableQuery 管理请求取消、竞态、分页和 loading;只需把 bindings 绑定给组件。rowKey 必须稳定且唯一,默认会检测缺失和重复键。
<script setup lang="ts">
import {
C_Table,
defineTableColumns,
defineTableConfig,
useTableQuery,
} from '@robot-admin/naive-ui-components/C_Table'
interface UserRow {
id: string
name: string
}
const columns = defineTableColumns<UserRow>([
{ key: 'name', title: '名称', editable: true },
])
const config = defineTableConfig<UserRow>({
selection: { enabled: true },
edit: {
enabled: true,
mode: 'row',
onSave: row => saveRow(row),
onError: error => reportError(error),
},
})
const { bindings } = useTableQuery<UserRow, { keyword: string }>({
initialQuery: { keyword: '' },
columns,
config,
rowKey: 'id',
request: async ({ page, pageSize, query, signal }) => {
const response = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify({ page, pageSize, ...query }),
signal,
})
return response.json() as Promise<{ data: UserRow[]; total: number }>
},
})
</script>
<template>
<C_Table v-bind="bindings" />
</template>
C_Map 推荐用法
C_Map 统一以 [纬度, 经度] 接收中心点和标记坐标;切换高德地图时会在组件内部转换为其要求的 [经度, 纬度],使用侧无需维护两套数据。非法标记会被隔离,组件只清理自己创建的 Marker,不会误删通过 ready 事件添加的业务图层。
<script setup lang="ts">
import { ref } from 'vue'
import {
C_Map,
type MapExpose,
type MapMarker,
} from '@robot-admin/naive-ui-components/C_Map'
import '@robot-admin/naive-ui-components/C_Map/style.css'
const mapRef = ref<MapExpose>()
const markers: MapMarker[] = [
{ id: 'beijing', lat: 39.9042, lng: 116.4074, popup: '北京' },
]
</script>
<template>
<C_Map
ref="mapRef"
:markers="markers"
fit-markers-on-init
:tile-config="{ maxZoom: 18 }"
@error="reportError"
/>
<button @click="mapRef?.fitToMarkers({ maxZoom: 14 })">定位全部标记</button>
</template>
组件实例提供 getMap()、refresh() 和 fitToMarkers(),适合标签页显示、容器尺寸变化和业务图层扩展。使用 map-type="amap" 时必须提供 amap-key;2021-12-02 之后申请的 Key 还必须按高德官方安全密钥说明配置 :amap-security-config="{ serviceHost: '/_AMapService' }"(生产推荐,由服务端代理保管安全密钥),或仅在开发环境传 { securityJsCode: '...' }。安全配置会在 SDK 脚本加载前写入,并拒绝同页混用不同 Key。宿主应用还需在 CSP 的 script-src 中允许 https://webapi.amap.com,同时在高德控制台配置域名白名单和配额限制。
C_Date、C_Time、C_Menu、C_FormSearch 均支持标准 v-model。组件可直接放在没有 NMessageProvider / NDialogProvider 的页面;如需统一提示、确认和文案,可在安装时传入 feedback、locale、form 与 table.defaults。
C_Captcha 服务端校验
默认本地模式仅证明浏览器内的拼图交互已经完成,不能作为登录、支付等敏感操作的安全凭证。生产场景应传入 verifier,并开启 require-server-verification;组件会处理超时、取消和竞态,只在独立的服务端/验证码提供商确认后发出 success。请求中的 token、timestamp 都由客户端生成,只能用于关联和日志,服务端绝不能把它们本身当作可信证明。
<C_Captcha
require-server-verification
:verification-timeout="8000"
:verifier="
async ({ signal }) => {
// providerProof 必须来自服务端或可信验证码提供商,不能由本地拼图结果伪造。
const providerProof = await obtainTrustedCaptchaProof({ signal })
const response = await fetch('/api/captcha/verify', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ providerProof }),
signal,
})
return response.json() // { valid: boolean, token: 'server-issued-token' }
}
"
@verify-error="reportError"
/>
开启 require-server-verification 后,成功响应必须包含服务端 token。该 token 应短期、一次性使用,并绑定当前会话或业务请求。C_Login 可通过 captchaVerifier、requireCaptchaServerVerification 和 captchaVerificationTimeout 透传同一安全策略,并在 submit 数据中通过 captchaVerifiedBy 标识验证来源。更多边界说明见 SECURITY.md。
📋 组件清单(51 个)
💡 所有组件均提供 在线交互演示,访问 组件文档 可直接在页面中体验真实效果(通过 iframe 嵌入 Robot Admin 生产环境)。
基础组件
| 组件 | 说明 | 外部依赖 |
|---|---|---|
C_Icon | Iconify 图标封装 | @iconify/vue |
C_Code | 代码高亮显示 | highlight.js |
C_Barcode | 条形码生成器 | @chenfengyuan/vue-barcode |
C_Captcha | 拼图验证码 | vue3-puzzle-vcode |
C_Cascade | 级联面板选择器 | - |
C_Guide | 新手引导 | driver.js |
C_Progress | 增强进度条 | - |
C_Steps | 步骤条 | - |
C_ActionBar | 操作按钮栏 | - |
C_Theme | 主题切换器 | - |
C_Language | 语言切换器 | - |
C_Date | 日期选择器增强 | - |
C_City | 省市区三级联动 | - |
C_Breadcrumb | 面包屑导航 | - |
C_Menu | 导航菜单 | - |
C_TagsView | 标签页导航 | - |
C_GlobalSearch | 全局搜索面板 | - |
C_AvatarGroup | 头像组合展示 | - |
C_OrgChart | 组织架构图 | - |
C_Skeleton | 骨架屏占位组件 | - |
内容 & 编辑组件
| 组件 | 说明 | 外部依赖 |
|---|---|---|
C_Editor | 富文本编辑器 | @wangeditor-next/editor |
C_Markdown | Markdown 编辑器/预览 | md-editor-v3 |
C_FormulaEditor | 公式编辑器(安全表达式引擎) | 内置 |
C_Signature | 电子签名 | - |
C_QRCode | 二维码生成器 | qrcode |
C_ImageCropper | 图片裁剪器 | vue-cropper |
数据展示组件
| 组件 | 说明 | 外部依赖 |
|---|---|---|
C_Table | 高级数据表格(CRUD/行列编辑/动态行/打印) | print-js、html2canvas |
C_Map | 地图组件(OSM/高德) | leaflet |
C_VtableGantt | 甘特图 | @visactor/vtable-gantt |
C_AntV | 图编辑器(ER/BPMN/UML) | @antv/x6、html2canvas |
C_WaterFall | 瀑布流布局 | - |
C_FullCalendar | 日历事件 | @fullcalendar/* |
C_VideoPlayer | 视频播放器(HLS/字幕/书签/章节) | xgplayer、xgplayer-hls |
C_AudioPlayer | 音频播放器(波形/进度/播放列表) | - |
C_FilePreview | 文件预览(PDF/Word/Excel) | xlsx、mammoth |
C_Timeline | 时间线(垂直/水平/可折叠) | - |
表单 & 布局组件
| 组件 | 说明 | 外部依赖 |
|---|---|---|
C_Form | 动态表单引擎(Grid/Tabs/Steps/Card/Dynamic 布局) | - |
C_FormSearch | 搜索表单 | - |
C_CollapsePanel | 折叠面板 | - |
C_SplitPane | 分割面板 | - |
C_Draggable | 拖拽排序 | vue-draggable-plus |
C_Tree | 高级树形控件 | - |
C_Time | 时间选择器增强 | - |
C_Cron | Cron 表达式编辑器 | - |
C_Transfer | 穿梭框(搜索/全选/批量操作) | - |
交互 & 业务组件
| 组件 | 说明 | 外部依赖 |
|---|---|---|
C_Chat | 聊天组件(联系人/消息气泡/输入框) | - |
C_ContextMenu | 右键菜单(嵌套子菜单/快捷键/危险操作) | - |
C_Login | 登录组件(5种模式/验证码/记住密码) | - |
流程 & 通知组件
| 组件 | 说明 | 外部依赖 |
|---|---|---|
C_WorkFlow | 工作流编辑器(审批/抄送/条件节点) | @vue-flow/core |
C_NotificationCenter | 通知中心(WebSocket/轮询) | - |
C_Upload | 大文件上传(分片/断点续传/哈希校验) | spark-md5 |
🔌 依赖说明
组件运行依赖已由本包声明,安装组件库时会自动解析。所有场景都需要:
bun add vue naive-ui
按功能安装可选 peer:使用 C_Breadcrumb/C_TagsView 时安装 vue-router;启用 C_Table 行/列拖拽时安装 sortablejs。子路径导入不会要求无关的可选 peer。公式编辑器使用组件库内置的受限表达式解析器,不执行动态 JavaScript。
🏗️ 构建架构
六阶段构建流水线
bun run build
├── 1. tsdown → 多入口打包(51 组件 ESM/CJS/DTS)
├── 2. sass CLI → 编译共享变量入口 → global-scss.css
├── 3. merge-css.js → 合并 Vue 编译后的 SFC CSS + 全局变量 → style.css
├── 4. gen-exports.js → 自动生成 package.json exports 映射
├── 5. check:dist → 校验根入口、子路径、SSR 及 DTS 公共导出
└── 6. check:size → 校验全量/基础样式与发布包体积预算
技术要点
- 构建引擎:tsdown(基于 Rolldown),51 个独立入口并行编译
- SCSS 处理:自定义
scssTransformPlugin在 Rolldown 管线内编译 SFC SCSS,独立 Sass CLI 仅编译共享变量入口 - CSS 合并:构建后将 Vue 已完成 scoped 转换的 per-chunk CSS 与共享变量合并为单一
style.css,避免重复样式和原始:deep()选择器泄漏 - 类型导出:统一
export *barrel 模式,自动生成完整.d.ts - 子路径导出:
gen-exports.js自动扫描dist/并写入package.json的exports字段 - 导出冲突检测:
check-export-conflicts.js确保组件间无命名冲突 - 产物入口校验:
check-dist-entries.js防止内部 chunk 覆盖根声明,并保证组件工具的子路径类型完整 - 包契约校验:禁止 Naive UI 内部类型路径、隐式可选依赖和插件控制台副作用
- 体积预算:
check-size-budget.js阻止全量样式、C_Form/C_Table 样式和 dist 总量意外膨胀
输出产物
dist/
├── index.js / index.cjs / index.d.ts # 主入口
├── C_Form.js / C_Form.cjs / C_Form.d.ts # 子路径入口(51 组件)
├── C_Form.base.css / C_Form.full.css # 基础/完整样式层级
├── C_Table.base.css / C_Table.full.css # 基础/完整样式层级
├── style.css # 合并后的全量样式
├── images/ # Leaflet Marker/图层控件资源
└── [chunk].js # 共享代码块
🔧 开发
环境基线为 Node.js 20.19.0+ 与 Bun 1.3.14;仓库通过 .node-version、packageManager、engines 和冻结锁文件保持本地/CI 一致。
bun install --frozen-lockfile # 严格按锁文件安装依赖
bun run dev # 开发模式(SCSS watch + tsdown watch)
bun run build # 完整构建
bun run build:scss # 仅编译全局 SCSS
bun run build:css # 合并 tsdown 刚生成的 CSS chunk;已完成的 dist 会安全跳过
bun run build:exports # 仅生成 exports 映射
bun run check:exports # 检测导出命名冲突
bun run check:dist # 校验构建后的 JS / DTS 公共入口
bun run check:package # 校验依赖、导出和源码公共边界
bun run check:quality # 防止 any、console 与类型抑制债务反弹
bun run check:audit # 审计直接与传递依赖漏洞
bun run check:size # 校验发布产物体积预算
bun run type-check # TypeScript 类型检查
bun run test # 运行 Bun 单元测试
bun run lint:check # 强制 Oxlint 正确性检查
bun run lint:eslint # ESLint 存量规则审计
bun run verify # 类型、测试、导出和构建全量验证
项目结构
naive-ui-components/
├── src/
│ ├── index.ts # 库入口(全量注册 + export * barrel)
│ ├── styles/
│ │ ├── variables.scss # CSS 变量 (--c-*)
│ │ └── global.scss # 自动生成的共享变量入口
│ ├── components/
│ │ └── C_[Name]/
│ │ ├── index.vue # 组件主文件
│ │ ├── index.ts # Barrel 导出
│ │ ├── index.scss # 组件样式
│ │ ├── types.ts # 类型定义
│ │ ├── constants.ts # 常量
│ │ ├── data.ts # 静态数据
│ │ ├── composables/ # 组合式函数
│ │ ├── components/ # 子组件
│ │ └── layouts/ # 布局变体(C_Form/C_AntV)
│ ├── plugins/ # highlight.js 等插件
│ └── utils/ # 工具函数
├── scripts/
│ ├── gen-global-scss.js # 生成 global.scss(仅共享变量)
│ ├── watch-global-scss.js # 开发模式 SCSS 监听
│ ├── merge-css.js # 合并 CSS 产物
│ ├── gen-exports.js # 自动生成 package.json exports
│ └── check-export-conflicts.js # 导出命名冲突检测
├── types/
│ └── env.d.ts # .vue / .scss 模块声明
├── tsdown.config.ts # 构建配置(多入口 + SCSS 插件 + Vue 插件)
└── tsconfig.json
添加新组件
- 创建
src/components/C_NewComponent/目录 - 编写
index.vue、index.ts(barrel)、types.ts - 在
src/index.ts中添加export * from './components/C_NewComponent' - 运行
bun run build—构建脚本会自动生成子路径入口和 exports 映射
发布
bun run changeset # 记录变更及版本级别
bun run version # 更新版本号与 CHANGELOG
bun run verify # 发布前完整验证
bun run release # 发布 Changesets 中待发布版本
📄 许可证
MIT License