CRUD组件
概述
CRUD组件是一套基于ArtTable封装的增删改查解决方案,提供了完整的数据管理功能。通过schema配置即可快速构建包含列表展示、搜索、新增、编辑、详情、删除等功能的管理界面。
基础用法
1. 引入组件
import { BasicCrud, useCrud } from '@/components/crud'
2. 定义CRUD结构
参考用户管理模块的配置:
import { CrudSchema } from '@/components/crud'
import { UserService } from '@/api/sys/user'
export const crudSchema: CrudSchema = {
// 接口地址
api: UserService.page,
dialogTitle: '用户',
crudApi: {
// 新增接口
add: UserService.save,
// 修改接口
edit: UserService.update,
// 删除接口
remove: UserService.remove,
// 详情接口
view: UserService.detail
},
// 使用crud
useCrud: true,
// 是否有新增
hasAdd: true,
// 是否有删除
hasRemove: true,
// 是否有修改
hasEdit: true,
// 是否有详情
hasView: true,
// 新增权限码
addAuth: 'sys:user:save',
// 删除权限码
removeAuth: 'sys:user:remove',
// 修改权限码
editAuth: 'sys:user:update',
// 详情权限码
viewAuth: 'sys:user:detail',
// 表格列定义
columns: [
{
type: 'selection'
},
{
prop: 'userName',
label: '用户名'
},
{
prop: 'realName',
label: '姓名'
}
],
// 搜索表单定义
searchFormSchema: {
schema: [
{
prop: 'm_LIKE_userName',
label: '用户名',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入用户名'
},
colSpan: 6
}
]
},
// 内置弹窗配置
dialogProps: {
dialogType: 'drawer'
},
// crud表单配置
formSchema: {
showDefaultActions: false,
labelWidth: '100px',
schema: [
{
label: '用户名',
prop: 'userName',
component: 'Input',
colSpan: 12,
rules: [
{
required: true,
message: '请输入用户名'
}
]
}
]
}
}
3. 在模板中使用
<template>
<div class="user-page art-full-height">
<BasicCrud />
</div>
</template>
<script setup lang="tsx">
import { useCrud } from '@/components/crud'
import { crudSchema } from './schemas'
const [BasicCrud] = useCrud({
...crudSchema
})
</script>
核心概念
CrudSchema 配置
| 属性 | 类型 | 说明 |
|---|---|---|
| rowKey | string | 行数据的唯一标识字段 |
| api | string | Function | 分页查询接口地址或方法 |
| requestMethod | 'get' | 'post' | 请求方法 |
| columns | CrudColumn[] | () => CrudColumn[] | 表格列配置,函数时才支持国际化 |
| useSearchForm | boolean | 是否使用搜索表单 |
| searchFormSchema | FormSchema | () => FormSchema | 搜索表单配置 |
| formSchema | FormSchema| () => FormSchema | 新增/编辑表单配置 |
| tableActions | ActionItem[] | 表格行操作按钮 |
| dropDownActions | ActionItem[] | 表格行下拉操作菜单 |
| toolbarActions | ActionItem[] | 工具栏操作按钮 |
| dropDownToolbarActions | ActionItem[] | 工具栏下拉操作菜单 |
| dialogProps | MyDialogProps | 内置弹窗配置 |
| crudApi | CrudApi | 增删改查接口配置 |
| useCrud | boolean | 是否启用内置CRUD功能 |
| dialogTitle | string | 模块名称 |
| hasAdd | boolean | 是否有新增功能 |
| addButtonText | string | 新增按钮文本 |
| addAuth | string | 新增按钮权限编码 |
| hasEdit | boolean | 是否有编辑功能 |
| editButtonText | string | 编辑按钮文本 |
| editAuth | string | 编辑按钮权限编码 |
| hasView | boolean | 是否有详情功能 |
| viewButtonText | string | 详情按钮文本 |
| viewAuth | string | 详情按钮权限编码 |
| hasRemove | boolean | 是否有删除功能 |
| removeButtonText | string | 删除按钮文本 |
| removeAuth | string | 删除按钮权限编码 |
CrudColumn 表格列配置
| 属性 | 类型 | 说明 |
|---|---|---|
| type | 'selection' | 'expand' | 'index' | 'globalIndex' | 列类型 |
| prop | string | 列属性名 |
| label | string | 列标题 |
| width | string | number | 列宽度 |
| minWidth | string | number | 最小列宽度 |
| fixed | boolean | 'left' | 'right' | 固定列 |
| sortable | boolean | 是否可排序 |
| filters | any[] | 过滤器选项 |
| filterMethod | Function | 过滤方法 |
| disabled | boolean | 是否禁用 |
| checked | boolean | 是否选中显示 |
| formatter | Function | 自定义渲染函数 |
| useSlot | boolean | 是否使用插槽渲染内容 |
| slotName | string | 插槽名称 |
| useHeaderSlot | boolean | 是否使用表头插槽 |
| headerSlotName | string | 表头插槽名称 |
| component | string | 列回显组件 |
| componentProps | Record<string, any> | 列回显组件属性 |
CrudApi 接口配置
| 属性 | 类型 | 说明 |
|---|---|---|
| add | Function | 新增接口 |
| edit | Function | 编辑接口 |
| remove | Function | 删除接口 |
| view | Function | 详情接口 |
CrudMethods 方法
| 方法名 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| getCrudRef | 无 | any | 获取表格实例 |
| setState | state: CrudSchema | Promise<void> | 设置组件状态(props) |
| getState | 无 | Promise<CrudSchema> | 获取组件状态 |
| getRowSelection | 无 | [] | 获取勾选行信息 |
| reload | params?: Record<string, any> | Promise<any> | 刷新表格数据,保留当前表单搜索条件 |
| getReadonlyState | 无 | CrudReadonlyState | 获取只读状态信息 |
| removeByApi | row: any | void | 通过接口删除行 |
| getArtTableInstance | 无 | any | 获取art表格实例,可通过该方法来操作原生的art-table组件 |
| refreshData | 无 | void | 全量刷新:清空所有缓存,重新获取数据(适用于手动刷新按钮) |
| refreshSoft | 无 | void | 轻量刷新:仅清空当前搜索条件的缓存,保持分页状态(适用于定时刷新) |
| refreshCreate | 无 | void | 新增后刷新:回到第一页并清空分页缓存(适用于新增数据后) |
| refreshUpdate | 无 | void | 更新后刷新:保持当前页,仅清空当前搜索缓存(适用于更新数据后) |
| refreshRemove | 无 | void | 删除后刷新:智能处理页码,避免空页面(适用于删除数据后) |
| openAddDialog | 无 | void | 打开内置新增表单 |
| openEditDialog | 无 | void | 打开内置修改表单 |
| openViewDialog | 无 | void | 打开内置详情表单 |
| executeRemove | 无 | void | 执行内置的删除方法-行删除 |
| executeBatchRemove | 无 | void | 执行内置的批量删除方法 |
内置功能
表格功能
- 分页功能 - 自动集成分页组件
- 列筛选 - 支持显示/隐藏列
- 刷新功能 - 支持手动刷新数据
- 行选择 - 支持单选/多选行数据
搜索功能
参考角色管理模块的搜索配置:
searchFormSchema: {
gutter: 20,
schema: [
{
prop: 'm_LIKE_name',
label: '角色名称',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入角色名称'
},
colSpan: 6
},
{
prop: 'm_LIKE_code',
label: '唯一编码',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入唯一编码'
},
colSpan: 6
},
{
prop: 'm_EQ_enabled',
label: '是否启用',
component: 'ApiDict',
componentProps: {
clearable: true,
code: 'yes_no',
placeholder: '请选择',
renderType: 'Select'
},
colSpan: 6
}
]
}
表单功能
参考用户管理模块的表单配置:
formSchema: {
showDefaultActions: false,
labelWidth: '100px',
schema: [
// 基础信息分隔符
{
prop: 'baseinfo',
label: '',
labelWidth: '0px',
component: 'Divider',
colSpan: 24,
componentProps: {
title: '基础信息'
}
},
// 用户名
{
label: '用户名',
prop: 'userName',
component: 'Input',
colSpan: 12,
rules: [
{
required: true,
message: '请输入用户名'
}
],
componentProps: {
placeholder: '请输入用户名',
clearable: true
}
}
]
}
操作按钮
CRUD组件内置了常用的操作按钮,也可通过配置添加自定义按钮:
const [BasicCrud] = useCrud({
...crudSchema,
// 左侧工具栏
toolbarActions: [
// 自定义按钮
{
label: '自定义操作',
type: 'primary',
auth: 'sys:user:custom',
onClick: () => {
// 自定义操作逻辑
}
}
],
// 表格行操作
tableActions: [
{
label: '详情',
type: 'primary',
link: true,
size: 'small',
auth: 'sys:user:detail'
}
]
})
CRUD方法调用样例
通过 useCrud可以调用以下方法:
const [BasicCrud, crudApi] = useCrud(crudSchema)
// 重新加载数据
crudApi.reload()
// 获取勾选行信息
crudApi.getRowSelection()
// 获取只读状态信息
crudApi.getReadonlyState()
// 通过接口删除行
crudApi.removeByApi(row)
// 设置组件状态
crudApi.setState(state)
// 获取组件状态
crudApi.getState()
// 刷新策略
crudApi.refreshData() // 全量刷新
crudApi.refreshSoft() // 轻量刷新
crudApi.refreshCreate() // 新增后刷新
crudApi.refreshUpdate() // 更新后刷新
crudApi.refreshRemove() // 删除后刷新
高级功能
(一)调整默认编辑按钮位置
- 先把默认编辑按钮隐藏
- 再增加自定义按钮
- 自定义按钮绑定事件,调用
crudApi.openEditDialog方法
具体例子可参考:角色管理
(二)行操作添加一个弹窗按钮
目录结构
src/views/sys/role
├── index.vue # 页面入口文件
└── auth-menu.vue # 添加一个授权菜单功能
- 新建弹窗组件
auth-menu.vue
具体例子可参考:角色管理
<template>
<Dialog> 我是弹窗内容 </Dialog>
</template>
<script setup lang="tsx">
import { useDialog } from '@/components/dialog'
import { CrudMethods } from '@/components/crud'
const record = ref<any>({})
const crudApi = ref<CrudMethods>()
const [Dialog, dialogApi] = useDialog({
title: '我是标题',
width: '50%'
})
defineExpose({
// 约定好的方法,由父组件调用打开,这里的data和getCrudApi为弹窗的参数dialogParams
show({ data, getCrudApi }: { data: any; getCrudApi: () => CrudMethods }) {
record.value = data
crudApi.value = getCrudApi()
dialogApi.open()
}
})
</script>
<style lang="scss" scoped></style>
- 入口页新增配置
index.vue
具体例子可参考:角色管理
<template>
<div class="sys-role-page art-full-height">
<BasicCrud />
<!-- 权限菜单 -->
<AuthMenu ref="authMenuRef" />
</div>
</template>
<script setup lang="tsx">
import { useCrud } from '@/components/crud'
import { crudSchema } from './schemas'
// 授权菜单组件
import AuthMenu from './auth-menu.vue'
// 授权菜单组件引用
const AuthMenuRef = ref()
const [BasicCrud] = useCrud({
...crudSchema,
toolbarActions: [],
dropDownToolbarActions: [],
// 这里是行操作按钮
tableActions: [{
label: '授权菜单',
type: 'primary',
sort: 1010,
link: true,
icon: 'ant-design:setting-outlined',
auth: 'sys:rbac:saveRoleMenu',
dialogRef: authMenuRef, // 弹窗组件的引用
dialogParams(record) {
// 这里返回的参数会传递给弹窗组件show 方法
return {
// 获取当前行数据
data: record,
// 获取当前crudApi
getCrudApi() {
return crudApi
}
}
}
}],
dropDownActions: []
})
</script>
<style lang="scss" scoped></style>
完整示例
参考角色管理模块的完整实现:
<template>
<div class="role-page art-full-height">
<BasicCrud />
</div>
</template>
<script setup lang="tsx">
import { useCrud } from '@/components/crud'
import { crudSchema } from './schemas'
const [BasicCrud] = useCrud({
...crudSchema
})
</script>
对应的schema配置参考角色模块:
import { RoleService } from '@/api/sys/role'
import { CrudSchema } from '@/components/crud'
export const crudSchema: CrudSchema = {
// 接口地址
api: RoleService.page,
dialogTitle: '角色',
crudApi: {
add: RoleService.save,
edit: RoleService.update,
remove: RoleService.remove,
view: RoleService.detail
},
useCrud: true,
hasAdd: true,
hasRemove: true,
hasEdit: true,
hasView: true,
addAuth: 'sys:role:save',
removeAuth: 'sys:role:remove',
editAuth: 'sys:role:update',
viewAuth: 'sys:role:detail',
columns: [
{
type: 'selection'
},
{
prop: 'name',
label: '角色名称'
},
{
prop: 'code',
label: '唯一编码'
}
],
searchFormSchema: {
gutter: 20,
schema: [
{
prop: 'm_LIKE_name',
label: '角色名称',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入角色名称'
},
colSpan: 6
}
]
},
dialogProps: {
width: '40%'
},
formSchema: {
showDefaultActions: false,
labelWidth: '100px',
schema: [
{
label: '角色名称',
prop: 'name',
component: 'Input',
colSpan: 24,
rules: [
{
required: true,
message: '请输入角色名称'
}
]
}
]
}
}
注意事项
- CRUD组件依赖于表单组件和对话框组件
- 接口返回的数据格式需要符合分页规范
- 操作按钮的权限控制通过
auth属性实现 - 表单配置遵循表单组件的schema规范
- 可通过
crudApi实现自定义的刷新策略
