Files
djangoadmin-wiki/DjangoAdmin_Django_EleVue/zh/volume4/frontend/components.md
T
2026-09-12 23:12:15 +08:00

25 KiB
Raw Blame History

公共组件库

:::tip 说明 项目提供丰富的公共组件,位于 ui/src/components/ 目录,基于 ElementPlus 二次封装,覆盖表格、表单、弹窗、上传、富文本编辑等常见场景。组件通过 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/ 图标(支持 ElementPlus 图标 + SVG 图标)
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 表格

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

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 列定义

属性 类型 说明
label string 列标题
prop string 字段名
width number 列宽
align string 对齐方式
type string 类型:index / selection
render Function 自定义渲染函数 (column, row, index) => VNode
isSlot boolean 是否使用插槽
ellipsis boolean 超出省略(tooltip)
auth string[] 权限编码,控制列是否显示
ifShow boolean | 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() 重新计算高度

基础用法

<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

属性 类型 默认值 说明
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 表单 章节。

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 渲染组件:Input / Select / DatePicker 等
componentProps object 组件属性
defaultValue any 默认值
rules object | object[] 字段校验规则
slot string 自定义插槽名
hidden boolean | Function 是否隐藏
colProps ColProps 栅格配置
labelMessage string 标签提示信息
suffix string 后缀文字

Events

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

Expose 方法

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

基础用法

<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

属性 类型 默认值 说明
title string '' 弹窗标题
width Number 446 弹窗宽度
draggable Boolean true 是否可拖拽
hideFooter Boolean false 隐藏底部按钮
confirmButText string '确认' 确认按钮文字
cancelButText string '取消' 取消按钮文字
confirmButProps Object - 确认按钮属性
cancelButProps Object - 取消按钮属性

Events

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

Expose 方法

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

基础用法

<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

属性 类型 默认值 说明
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) 删除文件

基础用法

<!-- 单图上传 -->
<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

属性 类型 默认值 说明
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' 图片上传接口

基础用法

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

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


CropperImage 图片裁剪

基于 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 - 裁剪出错

基础用法

<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

属性 类型 默认值 说明
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?) 下载二维码图片

基础用法

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

ChinaArea 省市区级联

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

Props

属性 类型 默认值 说明
modelValue String | Array - 双向绑定(区划编码数组)
type Number 3 联动级别:2(省市) / 3(省市区)
disabled Boolean false 是否禁用

Events

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

基础用法

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

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() 获取当前选项数据

基础用法

<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

属性 类型 默认值 说明
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 动画结束

基础用法

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

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() 触发校验显示

基础用法

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

PageWrapper 页面容器

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

Props

属性 类型 默认值 说明
title string '' 页面标题
content string '' 标题下方描述文字
contentStyle Object {} 主体区域样式
contentClass string '' 主体区域 class
showFooter Boolean true 是否显示底部

Slots

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

基础用法

<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

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

基础用法

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

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

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

:::


Icon 图标

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

Props

属性 类型 默认值 说明
name string (必填) 图标名称
size string | Number '14px' 图标大小
color string 'inherit' 图标颜色

基础用法

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

ImpExcel Excel 导入/导出

Excel 文件导入和导出组件。

导出函数

import { jsonToSheetXlsx, aoaToSheetXlsx } from '@/components/Excel';

// JSON 数据导出
jsonToSheetXlsx({
  data: [{ name: '张三', age: 25 }],
  header: { name: '姓名', age: '年龄' },
  filename: '用户列表.xlsx',
});

// 二维数组导出
aoaToSheetXlsx({
  data: [['姓名', '年龄'], ['张三', 25]],
  filename: '用户列表.xlsx',
});

导入组件

<template>
  <ImpExcel @success="handleImportSuccess" />
</template>

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

全局注册

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

// 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 操作列权限

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


总结

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