# 公共组件库 :::tip 说明 项目提供丰富的公共组件,位于 `ui/src/components/` 目录,基于 NaiveUI 二次封装,覆盖表格、表单、弹窗、上传、富文本编辑等常见场景。组件通过 `src/plugins/` 中的 `setupCustomComponents` 全局注册,任何页面直接使用,无需单独 import。 ::: ## 组件总览 | 组件 | 路径 | 说明 | |------|------|------| | BasicTable | `components/Table/` | 表格(列定义、分页、操作列、全屏、密度、斑马纹) | | TableAction | `components/Table/` | 操作列按钮组(权限控制、下拉折叠) | | BasicForm | `components/Form/` | 表单(schemas 配置化、动态渲染、折叠展开) | | BasicModal | `components/Modal/` | 弹窗(拖拽、全屏、自定义按钮) | | BasicUpload | `components/Upload/` | 文件/图片上传(卡片/列表、限制数量、预览) | | Editor | `components/Editor/` | 富文本编辑器(基于 wangeditor) | | CropperImage | `components/Cropper/` | 图片裁剪(圆形/矩形、实时预览) | | QrCode | `components/Qrcode/` | 二维码生成(canvas/img、内嵌 logo) | | ChinaArea | `components/ChinaArea/` | 省市区级联(懒加载、二/三级联动) | | Icon | `components/icon/` | 图标(支持 SVG 图标 + @vicons 图标库) | | BasicSelect | `components/Select/` | 增强下拉(远程请求、本地缓存) | | CountTo | `components/CountTo/` | 数字动画(前缀/后缀、千分位、缓动曲线) | | Password | `components/Password/` | 密码强度(强度指示器、重复确认、复杂度校验) | | PageWrapper | `components/Page/` | 页面容器(标题卡片、固定底部) | | Authority | `components/Authority/` | 权限容器(按权限码控制子元素渲染) | | LockScreen | `components/Lockscreen/` | 锁屏组件 | | ImpExcel | `components/Excel/` | Excel 导入/导出 | | AppProvider | `components/Application/` | 应用提供者(全局配置注入) | | Websocket | `components/Websocket/` | WebSocket 连接 | | importFile | `components/importFile/` | 通用文件导入 | | numberInput | `components/numberInput/` | 数字输入框 | | priceInput | `components/priceInput/` | 金额输入框 | | Region | `components/Region/` | 区域选择 | | TableSelect | `components/TableSelect/` | 表格选择器 | | pagination | `components/pagination/` | 分页组件 | --- ## BasicTable 表格 表格组件是使用频率最高的组件,基于 NaiveUI 的 `n-data-table` 封装,详见 [BasicTable 表格](/zh/volume4/frontend/table) 章节。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `columns` | `BasicColumn[]` | `[]`(必填) | 列定义 | | `request` | `Function` | `null` | 数据请求函数,自动管理分页和 loading | | `dataSource` | `Function \| Array` | `[]` | 数据源(与 request 二选一) | | `actionColumn` | `BasicColumn` | `null` | 操作列配置 | | `title` | `string` | `null` | 表格标题 | | `titleTooltip` | `string` | `null` | 标题提示 | | `pagination` | `Object \| Boolean` | `{}` | 分页配置,`false` 隐藏分页 | | `rowKey` | `string \| Function` | `undefined` | 行数据的唯一标识 | | `border` | `Boolean` | `false` | 是否显示边框 | | `striped` | `Boolean` | `false` | 斑马纹 | | `size` | `string` | `'default'` | 表格尺寸:`small` / `default` / `large` | | `tableHeight` | `Number \| String` | `null` | 固定表格高度 | | `maxHeight` | `Number` | - | 最大高度 | | `canResize` | `Boolean` | `true` | 是否自适应窗口高度 | | `resizeHeightOffset` | `Number` | `0` | 高度偏移量 | | `showTableSetting` | `Boolean` | `true` | 是否显示工具栏 | | `tableSetting` | `TableSetting` | 见下方 | 工具栏配置 | | `isKeepRowKeys` | `Boolean` | `false` | 翻页时是否保留选中行 | ### tableSetting 工具栏配置 | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `redo` | `Boolean` | `true` | 刷新按钮 | | `size` | `Boolean` | `true` | 密度切换 | | `setting` | `Boolean` | `true` | 列设置 | | `fullscreen` | `Boolean` | `true` | 全屏切换 | | `striped` | `Boolean` | `true` | 斑马纹开关 | ### BasicColumn 列定义 | 属性 | 类型 | 说明 | |------|------|------| | `title` | `string` | 列标题 | | `key` | `string` | 字段名 | | `width` | `number` | 列宽 | | `align` | `string` | 对齐方式 | | `type` | `string` | 类型:`selection` / `index` | | `render` | `Function` | 自定义渲染函数 `(record) => VNode` | | `isSlot` | `boolean` | 是否使用插槽 | | `ellipsis` | `boolean` | 超出省略(tooltip) | | `auth` | `string[]` | 权限编码,控制列是否显示 | | `ifShow` | `boolean \| Function` | 业务控制是否显示 | ### Events | 事件 | 参数 | 说明 | |------|------|------| | `fetch-success` | `(data, result)` | 数据请求成功 | | `fetch-error` | `(error)` | 数据请求失败 | | `update:checked-row-keys` | `(keys)` | 多选变化 | | `columns-change` | `(columns)` | 列设置变化 | | `checked-row-change` | `(rowKeys)` | 选中行变化 | ### Slots | 插槽 | 说明 | |------|------| | `tableTitle` | 表格标题左侧区域(常放添加按钮) | | `toolbar` | 工具栏右侧区域 | | `{key}` | 列名对应插槽,自定义列渲染 | ### Expose 方法 | 方法 | 说明 | |------|------| | `reload(opt?)` | 刷新表格(保留分页) | | `restReload(opt?)` | 重置到第一页并刷新 | | `reloadTable(opt?)` | 内部刷新(清空选中行) | | `getDataSource()` | 获取当前数据 | | `setTableData(data)` | 设置表格数据 | | `updateTableDataRecord(index, record)` | 更新指定行 | | `deleteTableDataRecord(index)` | 删除指定行 | | `getColumns()` | 获取列配置 | | `setColumns(columns)` | 设置列配置 | | `clearSelection()` | 清空多选 | | `setCheckedRowKeys(keys)` | 设置选中行 | | `redoHeight()` | 重新计算高度 | ### 基础用法 ```vue ``` --- ## TableAction 操作列 操作列按钮组件,支持权限控制和下拉折叠。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `actions` | `ActionItem[]` | (必填) | 操作按钮列表 | | `dropDownActions` | `ActionItem[]` | `null` | 下拉折叠操作列表 | | `dropDownProps` | `ActionItem` | `{ label: '更多' }` | 下拉按钮配置 | | `select` | `Function` | `() => {}` | 下拉选择回调 | ### ActionItem 配置 | 属性 | 类型 | 说明 | |------|------|------| | `label` | `string` | 按钮文字 | | `auth` | `string[]` | 权限编码 | | `onClick` | `Function` | 点击回调 | | `icon` | `Component` | 图标组件 | | `type` | `string` | 按钮类型 | | `disabled` | `boolean` | 是否禁用 | | `ifShow` | `boolean \| Function` | 是否显示 | | `isConfirm` | `boolean` | 是否需要确认 | | `popConfirm` | `object` | 气泡确认框配置 | --- ## BasicForm 表单 表单组件通过 schemas 配置化定义表单字段,支持动态渲染、折叠展开,详见 [BasicForm 表单](/zh/volume4/frontend/form) 章节。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `schemas` | `FormSchema[]` | `[]` | 表单字段配置 | | `model` | `Object` | - | 表单数据对象 | | `rules` | `FormRules` | - | 表单验证规则 | | `inline` | `Boolean` | `false` | 行内表单 | | `layout` | `string` | `'vertical'` | 布局方式 | | `labelPosition` | `string` | `'right'` | 标签位置 | | `labelWidth` | `Number \| String` | `80` | 标签宽度 | | `size` | `string` | `'default'` | 表单尺寸 | | `disabled` | `Boolean` | `false` | 禁用全部组件 | | `isFull` | `Boolean` | `true` | 组件是否 100% 宽度 | | `showActionButtonGroup` | `Boolean` | `true` | 显示操作按钮组 | | `showSubmitButton` | `Boolean` | `true` | 显示查询按钮 | | `showResetButton` | `Boolean` | `true` | 显示重置按钮 | | `showAdvancedButton` | `Boolean` | `true` | 显示展开/收起按钮 | | `submitButtonText` | `string` | `'查询'` | 查询按钮文字 | | `resetButtonText` | `string` | `'重置'` | 重置按钮文字 | | `collapsed` | `Boolean` | `true` | 是否默认折叠 | | `collapsedRows` | `Number` | `1` | 折叠时显示行数 | ### FormSchema 字段配置 | 属性 | 类型 | 说明 | |------|------|------| | `field` | `string` | 字段名(必填) | | `label` | `string` | 标签文字 | | `component` | `ComponentType` | 渲染组件:`NInput` / `NSelect` / `NDatePicker` 等 | | `componentProps` | `object` | 组件属性 | | `defaultValue` | `any` | 默认值 | | `rules` | `object \| object[]` | 字段校验规则 | | `slot` | `string` | 自定义插槽名 | | `hidden` | `boolean \| Function` | 是否隐藏 | | `gridProps` | `GridProps` | 栅格配置 | | `labelMessage` | `string` | 标签提示信息 | | `suffix` | `string` | 后缀文字 | ### Events | 事件 | 说明 | |------|------| | `submit` | 点击查询按钮 | | `reset` | 点击重置按钮 | ### Expose 方法 | 方法 | 说明 | |------|------| | `setFieldsValue(values)` | 设置字段值 | | `getFieldsValue()` | 获取所有字段值 | | `resetFields()` | 重置字段 | | `validate()` | 校验表单 | | `clearValidate(name?)` | 清除校验 | | `setProps(formProps)` | 设置属性 | | `setSchema(schemaProps)` | 动态修改 schema | ### 基础用法 ```vue ``` --- ## BasicModal 弹窗 弹窗组件基于 NaiveUI 的 `n-modal` 封装,支持拖拽、自定义按钮,详见 [Modal 弹窗](/zh/volume4/frontend/modal) 章节。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `title` | `string` | `''` | 弹窗标题 | | `width` | `Number` | `446` | 弹窗宽度 | | `draggable` | `Boolean` | `true` | 是否可拖拽 | | `hideFooter` | `Boolean` | `false` | 隐藏底部按钮 | | `confirmButText` | `string` | `'确认'` | 确认按钮文字 | | `cancelButText` | `string` | `'取消'` | 取消按钮文字 | | `confirmButProps` | `Object` | - | 确认按钮属性 | | `cancelButProps` | `Object` | - | 取消按钮属性 | ### Events | 事件 | 说明 | |------|------| | `on-ok` | 点击确认 | | `on-close` | 点击关闭 | | `register` | 弹窗注册回调 | ### Expose 方法 | 方法 | 说明 | |------|------| | `setModalProps(props)` | 设置弹窗属性 | | `openModal()` | 打开弹窗 | | `closeModal()` | 关闭弹窗 | ### 基础用法 ```vue ``` --- ## BasicUpload 上传 文件/图片上传组件,基于 NaiveUI 的 `n-upload` 封装,支持卡片/列表模式、数量限制、图片预览。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `listType` | `string` | `'picture-card'` | 展示类型:`picture-card` / `text` / `picture` | | `limit` | `Number` | `Infinity` | 最大上传数量 | | `maxSize` | `Number` | `2` | 文件大小上限(MB) | | `accept` | `string` | - | 接受的文件类型 | | `list` | `Ifiles[]` | `[]` | 已上传文件列表 | | `circle` | `Boolean` | `false` | 圆形裁剪 | | `uploadTitle` | `string` | `'上传图片'` | 列表模式按钮文字 | | `helpText` | `string` | `''` | 帮助提示文字 | | `width` | `Number` | `104` | 卡片宽度(px) | ### Events | 事件 | 参数 | 说明 | |------|------|------| | `uploadChange` | `(fileList)` | 上传/删除变化 | | `delete` | `(fileList)` | 删除文件 | ### 基础用法 ```vue ``` --- ## Editor 富文本编辑器 基于 [wangeditor](https://www.wangeditor.cn/) 封装,支持图片/视频上传、工具栏配置。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `getHtml` | `string` | - | 双向绑定(HTML 内容) | | `getText` | `string` | - | 双向绑定(纯文本) | | `height` | `string` | `'310'` | 编辑器高度 | | `width` | `string` | `'auto'` | 编辑器宽度 | | `mode` | `string` | `'default'` | 模式:`default` / `simple` | | `disable` | `Boolean` | `false` | 是否禁用 | | `placeholder` | `string` | `'请输入内容...'` | 占位文字 | | `uploadFileUrl` | `string` | `'/file/upload'` | 图片上传接口 | ### 基础用法 ```vue ``` :::warning 注意 编辑器内部自动处理图片上传,上传接口由 `uploadFileUrl` 配置。后端图片迁移和 XSS 清洗由 Service 层的 `rich_text_fields` 声明自动处理。 ::: --- ## CropperImage 图片裁剪 基于 [cropperjs](https://github.com/fengyuanchen/cropperjs) 封装,支持圆形/矩形裁剪、实时预览。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `src` | `string` | (必填) | 图片地址 | | `alt` | `string` | - | 图片描述 | | `circled` | `Boolean` | `false` | 圆形裁剪 | | `realTimePreview` | `Boolean` | `true` | 实时预览 | | `height` | `string \| Number` | `'360px'` | 裁剪区域高度 | | `imageStyle` | `CSSProperties` | `{}` | 图片样式 | | `options` | `Object` | `{}` | cropperjs 配置 | ### Events | 事件 | 参数 | 说明 | |------|------|------| | `cropend` | `{ imgBase64, imgInfo }` | 裁剪完成 | | `ready` | `(cropper)` | 裁剪器就绪 | | `cropendError` | - | 裁剪出错 | ### 基础用法 ```vue ``` --- ## QrCode 二维码生成 基于 [qrcode](https://github.com/soldair/node-qrcode) 封装,支持 canvas/img 渲染、内嵌 logo。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `value` | `string \| Array` | (必填) | 二维码内容 | | `width` | `Number` | `200` | 宽度(px) | | `tag` | `string` | `'canvas'` | 渲染方式:`canvas` / `img` | | `logo` | `string \| Object` | `''` | 中间 logo | | `options` | `Object` | `{}` | qrcode 配置项 | ### Events | 事件 | 参数 | 说明 | |------|------|------| | `done` | `{ url, ctx }` | 生成完成 | | `error` | `(error)` | 生成失败 | ### Expose 方法 | 方法 | 说明 | |------|------| | `download(fileName?)` | 下载二维码图片 | ### 基础用法 ```vue ``` --- ## ChinaArea 省市区级联 省市区三级联动选择器,基于后端城市接口懒加载。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `modelValue` | `String \| Array` | - | 双向绑定(区划编码数组) | | `type` | `Number` | `3` | 联动级别:`2`(省市) / `3`(省市区) | | `disabled` | `Boolean` | `false` | 是否禁用 | ### Events | 事件 | 参数 | 说明 | |------|------|------| | `update:modelValue` | `(codes)` | 值变化 | | `change` | `(text)` | 选中文本(如"浙江省杭州市西湖区") | ### 基础用法 ```vue ``` --- ## BasicSelect 增强下拉 远程数据下拉选择器,支持请求函数和本地缓存。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `request` | `Function` | (必填) | 获取选项数据的异步函数 | | `options` | `Array` | `[]` | 静态选项(与 request 二选一) | | `modelValue` | `String \| Number` | - | 双向绑定 | | `cache` | `Boolean` | `false` | 是否缓存到 localStorage | | `cacheKey` | `string` | `''` | 缓存 key(开启缓存时必填) | | `width` | `Number` | `150` | 宽度(px) | | `block` | `Boolean` | `false` | 100% 父容器宽度 | ### Expose 方法 | 方法 | 说明 | |------|------| | `fetch()` | 重新请求数据 | | `getData()` | 获取当前选项数据 | ### 基础用法 ```vue ``` --- ## CountTo 数字动画 数字动态递增/递减动画,支持前缀/后缀、千分位、缓动曲线。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `startVal` | `Number` | `0` | 起始值 | | `endVal` | `Number` | `2021` | 结束值 | | `duration` | `Number` | `1500` | 动画时长(ms) | | `autoplay` | `Boolean` | `true` | 自动播放 | | `decimals` | `Number` | `0` | 小数位数 | | `prefix` | `string` | `''` | 前缀 | | `suffix` | `string` | `''` | 后缀 | | `separator` | `string` | `','` | 千分位分隔符 | | `decimal` | `string` | `'.'` | 小数点符号 | | `color` | `string` | - | 字体颜色 | | `useEasing` | `Boolean` | `true` | 是否使用缓动 | | `transition` | `string` | `'linear'` | 缓动曲线 | ### Events | 事件 | 说明 | |------|------| | `onStarted` | 动画开始 | | `onFinished` | 动画结束 | ### 基础用法 ```vue ``` --- ## Password 密码强度 密码输入框,内置强度指示器、重复确认、复杂度校验。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `value` | `string` | - | 密码值 | | `repeat` | `Boolean` | `false` | 是否显示重复确认框 | | `required` | `Boolean` | `true` | 是否必填 | | `minLength` | `Number` | `6` | 最小长度 | | `maxLength` | `Number` | `32` | 最大长度 | | `complexity` | `Boolean` | `false` | 是否启用复杂度校验 | | `complexityTip` | `string` | - | 复杂度不满足时的提示 | | `width` | `Number` | `300` | 弹出框宽度 | | `block` | `Boolean` | `false` | 100% 宽度 | ### 强度等级 | 等级 | 条件 | 说明 | |------|------|------| | 0 | 无 | 极弱 | | 1 | 含小写或大写 | 弱 | | 2 | 含小写 + 大写,或含数字 | 中 | | 3 | 含小写 + 大写 + 数字 | 强 | | 4 | 含小写 + 大写 + 数字 + 特殊字符 | 极强 | ### Expose 方法 | 方法 | 说明 | |------|------| | `isValidator()` | 是否通过校验 | | `showValidator()` | 触发校验显示 | ### 基础用法 ```vue ``` --- ## PageWrapper 页面容器 页面容器组件,提供标题卡片和固定底部区域。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `title` | `string` | `''` | 页面标题 | | `content` | `string` | `''` | 标题下方描述文字 | | `contentStyle` | `Object` | `{}` | 主体区域样式 | | `contentClass` | `string` | `''` | 主体区域 class | | `showFooter` | `Boolean` | `true` | 是否显示底部 | ### Slots | 插槽 | 说明 | |------|------| | `headerContent` | 标题卡片内容区域 | | `default` | 页面主体内容 | | `leftFooter` | 底部左侧(常放操作按钮) | | `rightFooter` | 底部右侧 | ### 基础用法 ```vue ``` --- ## Authority 权限容器 按权限码控制子元素是否渲染,类似 `v-perm` 指令的组件形式。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `value` | `string[]` | `[]` | 权限编码数组 | ### 基础用法 ```vue ``` :::tip v-perm 指令 除了 `Authority` 组件,项目还提供 `v-perm` 指令,功能相同但更简洁: ```vue 新增用户 ``` ::: --- ## Icon 图标 统一图标组件,支持 SVG 图标和 @vicons 图标库。 ### Props | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `name` | `string` | (必填) | 图标名称 | | `size` | `string \| Number` | `'14px'` | 图标大小 | | `color` | `string` | `'inherit'` | 图标颜色 | ### 基础用法 ```vue ``` --- ## ImpExcel Excel 导入/导出 Excel 文件导入和导出组件。 ### 导出函数 ```typescript import { jsonToSheetXlsx, aoaToSheetXlsx } from '@/components/Excel'; // JSON 数据导出 jsonToSheetXlsx({ data: [{ name: '张三', age: 25 }], header: { name: '姓名', age: '年龄' }, filename: '用户列表.xlsx', }); // 二维数组导出 aoaToSheetXlsx({ data: [['姓名', '年龄'], ['张三', 25]], filename: '用户列表.xlsx', }); ``` ### 导入组件 ```vue ``` --- ## 全局注册 所有组件在 `src/plugins/setupCustomComponents.ts` 中通过 `setupCustomComponents` 全局注册: ```typescript // main.ts import { setupCustomComponents } from '/@/plugins'; setupCustomComponents(app); // 注册所有自定义组件 ``` 全局注册后,任何组件中直接使用,无需单独 import。 --- ## 权限控制体系 项目提供三种权限控制方式,覆盖不同场景: | 方式 | 语法 | 适用场景 | |------|------|----------| | `v-perm` 指令 | `v-perm="['sys:user:add']"` | 按钮级权限,最常用 | | `Authority` 组件 | `` | 容器级权限,控制多个元素 | | `auth` 列属性 | `{ auth: ['sys:user:delete'] }` | TableAction 操作列权限 | :::warning 注意 `v-perm` 和 `Authority` 的权限码必须与后端 `@permission_required("sys:xxx:xxx")` 一致。用户 ID 1(admin)拥有所有权限。 ::: --- ## 总结 公共组件库基于 NaiveUI 二次封装,核心三件套 BasicTable(表格)、BasicForm(表单)、BasicModal(弹窗)覆盖列表页标准场景。辅以 Upload、Editor、Cropper 等业务组件,以及 Authority、v-perm 权限体系。通过全局注册,任何页面直接使用,无需单独 import。优先使用公共组件,避免重复开发。