Skip to content

公共组件库

说明

项目提供丰富的公共组件,位于 ui/src/components/ 目录,基于 ElementPlus 二次封装,覆盖表格、表单、弹窗、上传、富文本编辑等常见场景。组件通过 src/plugins/ 中的 setupCustomComponents 全局注册,任何页面直接使用,无需单独 import。

组件总览

组件路径说明
BasicTablecomponents/Table/表格(列定义、分页、操作列、全屏、密度、斑马纹)
TableActioncomponents/Table/操作列按钮组(权限控制、下拉折叠)
BasicFormcomponents/Form/表单(schemas 配置化、动态渲染、折叠展开)
BasicModalcomponents/Modal/弹窗(拖拽、全屏、自定义按钮)
BasicUploadcomponents/Upload/文件/图片上传(卡片/列表、限制数量、预览)
Editorcomponents/Editor/富文本编辑器(基于 wangeditor)
CropperImagecomponents/Cropper/图片裁剪(圆形/矩形、实时预览)
QrCodecomponents/Qrcode/二维码生成(canvas/img、内嵌 logo)
ChinaAreacomponents/ChinaArea/省市区级联(懒加载、二/三级联动)
Iconcomponents/icon/图标(支持 ElementPlus 图标 + SVG 图标)
BasicSelectcomponents/Select/增强下拉(远程请求、本地缓存)
CountTocomponents/CountTo/数字动画(前缀/后缀、千分位、缓动曲线)
Passwordcomponents/Password/密码强度(强度指示器、重复确认、复杂度校验)
PageWrappercomponents/Page/页面容器(标题卡片、固定底部)
Authoritycomponents/Authority/权限容器(按权限码控制子元素渲染)
LockScreencomponents/Lockscreen/锁屏组件
ImpExcelcomponents/Excel/Excel 导入/导出
AppProvidercomponents/Application/应用提供者(全局配置注入)
Websocketcomponents/Websocket/WebSocket 连接
importFilecomponents/importFile/通用文件导入
numberInputcomponents/numberInput/数字输入框
priceInputcomponents/priceInput/金额输入框
Regioncomponents/Region/区域选择
TableSelectcomponents/TableSelect/表格选择器
paginationcomponents/pagination/分页组件

BasicTable 表格

表格组件是使用频率最高的组件,基于 el-table + el-pagination 封装,详见 BasicTable 表格 章节。

Props

属性类型默认值说明
columnsBasicColumn[][](必填)列定义
requestFunctionnull数据请求函数,自动管理分页和 loading
dataSourceFunction | Array[]数据源(与 request 二选一)
actionColumnBasicColumnnull操作列配置
titlestringnull表格标题
titleTooltipstringnull标题提示
paginationObject | Boolean{}分页配置,false 隐藏分页
rowKeystring | Functionundefined行数据的唯一标识
borderBooleanfalse是否显示边框
stripedBooleanfalse斑马纹
sizestring'default'表格尺寸:small / default / large
tableHeightNumber | Stringnull固定表格高度
maxHeightNumber-最大高度
canResizeBooleantrue是否自适应窗口高度
resizeHeightOffsetNumber0高度偏移量
showTableSettingBooleantrue是否显示工具栏
tableSettingTableSetting见下方工具栏配置
isKeepRowKeysBooleanfalse翻页时是否保留选中行

tableSetting 工具栏配置

属性类型默认值说明
redoBooleantrue刷新按钮
sizeBooleantrue密度切换
settingBooleantrue列设置
fullscreenBooleantrue全屏切换
stripedBooleantrue斑马纹开关

BasicColumn 列定义

属性类型说明
labelstring列标题
propstring字段名
widthnumber列宽
alignstring对齐方式
typestring类型:index / selection
renderFunction自定义渲染函数 (column, row, index) => VNode
isSlotboolean是否使用插槽
ellipsisboolean超出省略(tooltip)
authstring[]权限编码,控制列是否显示
ifShowboolean | Function业务控制是否显示

Events

事件参数说明
fetch-success(data, result)数据请求成功
fetch-error(error)数据请求失败
selection-change(rows)多选变化
columns-change(columns)列设置变化
checked-row-change(rowKeys)选中行变化

Slots

插槽说明
tableTitle表格标题左侧区域(常放添加按钮)
toolbar工具栏右侧区域
{prop}列名对应插槽,自定义列渲染

Expose 方法

方法说明
reload(opt?)刷新表格(保留分页)
restReload(opt?)重置到第一页并刷新
reloadTable(opt?)内部刷新(清空选中行)
getDataSource()获取当前数据
setTableData(data)设置表格数据
updateTableDataRecord(index, record)更新指定行
deleteTableDataRecord(index)删除指定行
getColumns()获取列配置
setColumns(columns)设置列配置
clearSelection()清空多选
setCheckedRowKeys(keys)设置选中行
redoHeight()重新计算高度

基础用法

vue
<template>
  <BasicTable :columns="columns" :request="loadDataTable" ref="tableRef">
    <template #tableTitle>
      <el-button v-perm="['sys:level:add']" type="primary" @click="handleAdd">
        <el-icon><Plus /></el-icon>新增
      </el-button>
    </template>
  </BasicTable>
</template>

<script setup lang="ts">
const columns = [
  { label: '名称', prop: 'name', width: 200 },
  { label: '状态', prop: 'status', width: 100 },
  { label: '创建时间', prop: 'createTime', width: 180 },
];

const actionColumn = {
  width: 200,
  actions: [
    { label: '编辑', auth: ['sys:level:update'], onClick: handleEdit },
    {
      label: '删除',
      auth: ['sys:level:delete'],
      isConfirm: true,
      popConfirm: { title: '确认删除?' },
      onClick: handleDelete,
    },
  ],
};

async function loadDataTable({ page, pageSize }) {
  const res = await getListApi({ pageNo: page, pageSize });
  return { items: res.data, total: res.count };
}
</script>

TableAction 操作列

操作列按钮组件,支持权限控制和下拉折叠。

Props

属性类型默认值说明
actionsActionItem[](必填)操作按钮列表
dropDownActionsActionItem[]null下拉折叠操作列表
dropDownPropsActionItem{ label: '更多' }下拉按钮配置
selectFunction() => {}下拉选择回调

ActionItem 配置

属性类型说明
labelstring按钮文字
authstring[]权限编码
onClickFunction点击回调
iconComponent图标组件
typestring按钮类型
disabledboolean是否禁用
ifShowboolean | Function是否显示
isConfirmboolean是否需要确认
popConfirmobject气泡确认框配置

BasicForm 表单

表单组件通过 schemas 配置化定义表单字段,支持动态渲染、折叠展开,详见 BasicForm 表单 章节。

Props

属性类型默认值说明
schemasFormSchema[][]表单字段配置
modelObject-表单数据对象
rulesFormRules-表单验证规则
inlineBooleanfalse行内表单
layoutstring'vertical'布局方式
labelPositionstring'right'标签位置
labelWidthNumber | String80标签宽度
sizestring'default'表单尺寸
disabledBooleanfalse禁用全部组件
isFullBooleantrue组件是否 100% 宽度
showActionButtonGroupBooleantrue显示操作按钮组
showSubmitButtonBooleantrue显示查询按钮
showResetButtonBooleantrue显示重置按钮
showAdvancedButtonBooleantrue显示展开/收起按钮
submitButtonTextstring'查询'查询按钮文字
resetButtonTextstring'重置'重置按钮文字
collapsedBooleantrue是否默认折叠
collapsedRowsNumber1折叠时显示行数

FormSchema 字段配置

属性类型说明
fieldstring字段名(必填)
labelstring标签文字
componentComponentType渲染组件:Input / Select / DatePicker
componentPropsobject组件属性
defaultValueany默认值
rulesobject | object[]字段校验规则
slotstring自定义插槽名
hiddenboolean | Function是否隐藏
colPropsColProps栅格配置
labelMessagestring标签提示信息
suffixstring后缀文字

Events

事件说明
submit点击查询按钮
reset点击重置按钮

Expose 方法

方法说明
setFieldsValue(values)设置字段值
getFieldsValue()获取所有字段值
resetFields()重置字段
validate()校验表单
clearValidate(name?)清除校验
setProps(formProps)设置属性
setSchema(schemaProps)动态修改 schema

基础用法

vue
<template>
  <BasicForm @register="registerForm" @submit="handleSearch" @reset="handleReset" />
</template>

<script setup lang="ts">
const [registerForm] = useForm({
  schemas: [
    {
      field: 'name',
      label: '名称',
      component: 'Input',
      componentProps: { placeholder: '请输入名称' },
    },
    {
      field: 'status',
      label: '状态',
      component: 'Select',
      componentProps: {
        options: [
          { label: '启用', value: 1 },
          { label: '禁用', value: 0 },
        ],
      },
    },
    {
      field: 'dateRange',
      label: '日期范围',
      component: 'DatePicker',
      componentProps: { type: 'daterange' },
    },
  ],
});
</script>

BasicModal 弹窗

弹窗组件基于 el-dialog 封装,支持拖拽、自定义按钮,详见 Modal 弹窗 章节。

Props

属性类型默认值说明
titlestring''弹窗标题
widthNumber446弹窗宽度
draggableBooleantrue是否可拖拽
hideFooterBooleanfalse隐藏底部按钮
confirmButTextstring'确认'确认按钮文字
cancelButTextstring'取消'取消按钮文字
confirmButPropsObject-确认按钮属性
cancelButPropsObject-取消按钮属性

Events

事件说明
ok点击确认
register弹窗注册回调

Expose 方法

方法说明
setModalProps(props)设置弹窗属性
openModal()打开弹窗
closeModal()关闭弹窗

基础用法

vue
<template>
  <BasicModal title="编辑用户" :width="600" @register="registerModal" @ok="handleSubmit">
    <BasicForm @register="registerForm" />
  </BasicModal>
</template>

<script setup lang="ts">
const [registerModal, { openModal, closeModal, setModalProps }] = useModal();

function handleEdit(record) {
  setModalProps({ title: '编辑用户' });
  openModal();
  // 回填表单数据
  nextTick(() => {
    setFieldsValue(record);
  });
}
</script>

BasicUpload 上传

文件/图片上传组件,基于 el-upload 封装,支持卡片/列表模式、数量限制、图片预览。

Props

属性类型默认值说明
listTypestring'picture-card'展示类型:picture-card / text / picture
limitNumberInfinity最大上传数量
maxSizeNumber2文件大小上限(MB)
acceptstring-接受的文件类型
listIfiles[][]已上传文件列表
circleBooleanfalse圆形裁剪
uploadTitlestring'上传图片'列表模式按钮文字
helpTextstring''帮助提示文字
widthNumber104卡片宽度(px)

Events

事件参数说明
uploadChange(fileList)上传/删除变化
delete(fileList)删除文件

基础用法

vue
<!-- 单图上传 -->
<Upload v-model="formData.cover" :limit="1" accept="image/*" />

<!-- 多图上传 -->
<Upload :list="formData.images" :limit="5" @uploadChange="handleImageChange" />

<!-- 文件上传 -->
<Upload list-type="text" accept=".pdf,.doc,.docx" uploadTitle="上传附件" />

Editor 富文本编辑器

基于 wangeditor 封装,支持图片/视频上传、工具栏配置。

Props

属性类型默认值说明
getHtmlstring-双向绑定(HTML 内容)
getTextstring-双向绑定(纯文本)
heightstring'310'编辑器高度
widthstring'auto'编辑器宽度
modestring'default'模式:default / simple
disableBooleanfalse是否禁用
placeholderstring'请输入内容...'占位文字
uploadFileUrlstring'/file/upload'图片上传接口

基础用法

vue
<template>
  <Editor v-model:getHtml="formData.content" height="400px" />
</template>

注意

编辑器内部自动处理图片上传,上传接口由 uploadFileUrl 配置。后端图片迁移和 XSS 清洗由 Service 层的 rich_text_fields 声明自动处理。


CropperImage 图片裁剪

基于 cropperjs 封装,支持圆形/矩形裁剪、实时预览。

Props

属性类型默认值说明
srcstring(必填)图片地址
altstring-图片描述
circledBooleanfalse圆形裁剪
realTimePreviewBooleantrue实时预览
heightstring | Number'360px'裁剪区域高度
imageStyleCSSProperties{}图片样式
optionsObject{}cropperjs 配置

Events

事件参数说明
cropend{ imgBase64, imgInfo }裁剪完成
ready(cropper)裁剪器就绪
cropendError-裁剪出错

基础用法

vue
<template>
  <CropperImage
    :src="formData.avatar"
    :circled="true"
    height="300px"
    @cropend="handleCropend"
  />
</template>

<script setup lang="ts">
function handleCropend({ imgBase64, imgInfo }) {
  // imgBase64: base64 格式的裁剪结果
  // imgInfo: 裁剪区域坐标和尺寸
  formData.value.avatar = imgBase64;
}
</script>

QrCode 二维码生成

基于 qrcode 封装,支持 canvas/img 渲染、内嵌 logo。

Props

属性类型默认值说明
valuestring | Array(必填)二维码内容
widthNumber200宽度(px)
tagstring'canvas'渲染方式:canvas / img
logostring | Object''中间 logo
optionsObject{}qrcode 配置项

Events

事件参数说明
done{ url, ctx }生成完成
error(error)生成失败

Expose 方法

方法说明
download(fileName?)下载二维码图片

基础用法

vue
<template>
  <QrCode value="https://www.example.com" :width="200" :logo="logoUrl" />
</template>

ChinaArea 省市区级联

省市区三级联动选择器,基于后端城市接口懒加载。

Props

属性类型默认值说明
modelValueString | Array-双向绑定(区划编码数组)
typeNumber3联动级别:2(省市) / 3(省市区)
disabledBooleanfalse是否禁用

Events

事件参数说明
update:modelValue(codes)值变化
change(text)选中文本(如"浙江省杭州市西湖区")

基础用法

vue
<template>
  <ChinaArea v-model="formData.cityCode" :type="3" @change="handleCityChange" />
</template>

BasicSelect 增强下拉

远程数据下拉选择器,支持请求函数和本地缓存。

Props

属性类型默认值说明
requestFunction(必填)获取选项数据的异步函数
optionsArray[]静态选项(与 request 二选一)
modelValueString | Number-双向绑定
cacheBooleanfalse是否缓存到 localStorage
cacheKeystring''缓存 key(开启缓存时必填)
widthNumber150宽度(px)
blockBooleanfalse100% 父容器宽度

Expose 方法

方法说明
fetch()重新请求数据
getData()获取当前选项数据

基础用法

vue
<template>
  <BasicSelect
    v-model="formData.deptId"
    :request="getDeptOptions"
    :cache="true"
    cacheKey="dept-options"
    placeholder="请选择部门"
  />
</template>

<script setup lang="ts">
async function getDeptOptions() {
  const res = await getDeptListApi();
  return res.data.map(item => ({ label: item.name, value: item.id }));
}
</script>

CountTo 数字动画

数字动态递增/递减动画,支持前缀/后缀、千分位、缓动曲线。

Props

属性类型默认值说明
startValNumber0起始值
endValNumber2021结束值
durationNumber1500动画时长(ms)
autoplayBooleantrue自动播放
decimalsNumber0小数位数
prefixstring''前缀
suffixstring''后缀
separatorstring','千分位分隔符
decimalstring'.'小数点符号
colorstring-字体颜色
useEasingBooleantrue是否使用缓动
transitionstring'linear'缓动曲线

Events

事件说明
onStarted动画开始
onFinished动画结束

基础用法

vue
<template>
  <CountTo :endVal="12345" :duration="2000" prefix="¥" separator="," />
</template>

Password 密码强度

密码输入框,内置强度指示器、重复确认、复杂度校验。

Props

属性类型默认值说明
valuestring-密码值
repeatBooleanfalse是否显示重复确认框
requiredBooleantrue是否必填
minLengthNumber6最小长度
maxLengthNumber32最大长度
complexityBooleanfalse是否启用复杂度校验
complexityTipstring-复杂度不满足时的提示
widthNumber300弹出框宽度
blockBooleanfalse100% 宽度

强度等级

等级条件说明
0极弱
1含小写或大写
2含小写 + 大写,或含数字
3含小写 + 大写 + 数字
4含小写 + 大写 + 数字 + 特殊字符极强

Expose 方法

方法说明
isValidator()是否通过校验
showValidator()触发校验显示

基础用法

vue
<template>
  <Password v-model:value="formData.password" :repeat="true" :complexity="true" />
</template>

PageWrapper 页面容器

页面容器组件,提供标题卡片和固定底部区域。

Props

属性类型默认值说明
titlestring''页面标题
contentstring''标题下方描述文字
contentStyleObject{}主体区域样式
contentClassstring''主体区域 class
showFooterBooleantrue是否显示底部

Slots

插槽说明
headerContent标题卡片内容区域
default页面主体内容
leftFooter底部左侧(常放操作按钮)
rightFooter底部右侧

基础用法

vue
<template>
  <PageWrapper title="用户管理" content="管理系统用户信息">
    <BasicTable :columns="columns" :request="loadData" />

    <template #leftFooter>
      <el-button @click="handleCancel">取消</el-button>
    </template>
    <template #rightFooter>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
    </template>
  </PageWrapper>
</template>

Authority 权限容器

按权限码控制子元素是否渲染,类似 v-perm 指令的组件形式。

Props

属性类型默认值说明
valuestring[][]权限编码数组

基础用法

vue
<template>
  <Authority :value="['sys:user:add']">
    <el-button type="primary">新增用户</el-button>
  </Authority>
</template>

v-perm 指令

除了 Authority 组件,项目还提供 v-perm 指令,功能相同但更简洁:

vue
<el-button v-perm="['sys:user:add']">新增用户</el-button>

Icon 图标

统一图标组件,支持 ElementPlus 图标和 SVG 图标。

Props

属性类型默认值说明
namestring(必填)图标名称
sizestring | Number'14px'图标大小
colorstring'inherit'图标颜色

基础用法

vue
<template>
  <!-- ElementPlus 图标 -->
  <Icon name="el-icon-Plus" size="18px" />
  <!-- SVG 图标 -->
  <Icon name="svg-icon-user" />
</template>

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
<template>
  <ImpExcel @success="handleImportSuccess" />
</template>

<script setup lang="ts">
function handleImportSuccess(data) {
  // data: 导入的表格数据
  console.log(data);
}
</script>

全局注册

所有组件在 src/plugins/setupCustomComponents.ts 中通过 setupCustomComponents 全局注册:

typescript
// main.ts
import { setupCustomComponents } from '/@/plugins';

setupCustomComponents(app); // 注册所有自定义组件

全局注册后,任何组件中直接使用,无需单独 import。


权限控制体系

项目提供三种权限控制方式,覆盖不同场景:

方式语法适用场景
v-perm 指令v-perm="['sys:user:add']"按钮级权限,最常用
Authority 组件<Authority :value="['sys:user:add']">容器级权限,控制多个元素
auth 列属性{ auth: ['sys:user:delete'] }TableAction 操作列权限

注意

v-permAuthority 的权限码必须与后端 @permission_required("sys:xxx:xxx") 一致。用户 ID 1(admin)拥有所有权限。


总结

公共组件库基于 ElementPlus 二次封装,核心三件套 BasicTable(表格)、BasicForm(表单)、BasicModal(弹窗)覆盖列表页标准场景。辅以 Upload、Editor、Cropper 等业务组件,以及 Authority、v-perm 权限体系。通过全局注册,任何页面直接使用,无需单独 import。优先使用公共组件,避免重复开发。

小蚂蚁云团队 · 提供技术支持