详情组件
概述
详情组件是一套基于 Element Plus 封装的数据展示解决方案,用于展示表单数据的只读视图。通过 schema 配置即可快速构建数据详情页面,支持多种数据展示组件和灵活的配置方式。
快速开始
1. 引入组件
import { DetailForm, useDetailForm } from '@/components/form'
2. 定义详情结构
const schema = [
{
prop: 'name',
label: '姓名',
component: 'Input'
},
{
prop: 'email',
label: '邮箱',
component: 'Input'
}
]
const [DetailForm, detailFormApi] = useDetailForm({
labelPosition: 'right',
labelWidth: '100px',
schema: schema
})
3. 在模板中使用
<template>
<DetailForm :model="detailData" />
</template>
核心概念
DetailForm 配置
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
labelPosition | 'left' | 'right' | 'top' | 'right' | 标签位置 |
gutter | number | 0 | 栅格间隔 |
labelWidth | string | '80px' | 标签宽度 |
schema | FormItemSchema[] | [] | 详情项配置 |
border | boolean | true | 是否显示边框 |
FormItemSchema 详情项配置
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
prop | string | 是 | 详情项属性名 |
label | string | 是 | 详情项标签 |
component | string | 是 | 详情项组件类型 |
labelWidth | string | number | 否 | 标签宽度 |
colSpan | number | 否 | 栅格列数(1-24) |
componentProps | Record | Function | 否 | 组件属性配置 |
ifDetail | boolean | Function | 否 | 动态显示控制 |
helpMessage | string | string[] | 否 | 帮助提示信息 |
内置详情组件
基础展示组件
- Select - 基础数据展示
{
prop: 'status',
label: '状态',
component: 'Select',
componentProps: {
options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 }
]
}
}
- DatePicker - 日期展示
{
prop: 'createTime',
label: '创建时间',
component: 'DatePicker'
}
- RadioGroup - 单选展示
{
prop: 'gender',
label: '性别',
component: 'RadioGroup',
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 }
]
}
}
- CheckboxGroup - 多选展示
{
prop: 'hobbies',
label: '爱好',
component: 'CheckboxGroup',
componentProps: {
options: [
{ label: '读书', value: 'reading' },
{ label: '游泳', value: 'swimming' }
]
}
}
远程数据展示组件
- ApiSelect - 远程数据展示
{
prop: 'userId',
label: '用户',
component: 'ApiSelect',
componentProps: {
api: '/api/user/select'
}
}
- ApiRadioGroup - 远程单选展示
{
prop: 'categoryId',
label: '分类',
component: 'ApiRadioGroup',
componentProps: {
api: '/api/category/select'
}
}
- ApiCheckboxGroup - 远程多选展示
{
prop: 'tagIds',
label: '标签',
component: 'ApiCheckboxGroup',
componentProps: {
api: '/api/tag/select'
}
}
- ApiTreeSelect - 远程树形数据展示
{
prop: 'deptId',
label: '部门',
component: 'ApiTreeSelect',
componentProps: {
api: '/api/dept/tree'
}
}
- ApiCascader - 远程级联数据展示
{
prop: 'areaCode',
label: '地区',
component: 'ApiCascader',
componentProps: {
api: '/api/area/tree'
}
}
字典展示组件
{
prop: 'sex',
label: '性别',
component: 'ApiDict',
componentProps: {
code: 'sex'
}
}
字典组件支持标签样式展示:
{
prop: 'status',
label: '状态',
component: 'ApiDict',
componentProps: {
code: 'status',
typeMap: {
'1': 'success',
'0': 'danger'
},
colorMap: {
'1': { textColor: '#52c41a', bgColor: '#f6ffed' },
'0': { textColor: '#ff4d4f', bgColor: '#fff2f0' }
}
}
}
特殊展示组件
- Upload - 文件展示
{
prop: 'attachments',
label: '附件',
component: 'Upload',
componentProps: {
listType: 'text' // text/picture/picture-card
}
}
- Editor - 富文本展示
{
prop: 'content',
label: '内容',
component: 'Editor'
}
- IconPicker - 图标展示
{
prop: 'icon',
label: '图标',
component: 'IconPicker'
}
- Avatar - 头像展示
{
prop: 'avatar',
label: '头像',
component: 'Avatar'
}
布局组件
- Divider - 分割线
{
prop: 'divider-basic',
label: '',
labelWidth: '0px',
component: 'Divider',
colSpan: 24,
componentProps: {
title: '基本信息'
}
}
高级功能
动态显示控制
通过 ifDetail
属性控制详情项的显示:
{
prop: 'type',
label: '类型',
component: 'Select',
componentProps: {
options: [
{ label: '类型1', value: 1 },
{ label: '类型2', value: 2 }
]
}
},
{
prop: 'field1',
label: '字段1',
component: 'Input',
ifDetail: (values) => values.type === 1 // 当type为1时显示
}
动态属性配置
通过函数形式的 componentProps
实现动态属性:
{
prop: 'remark',
label: '备注',
component: 'Input',
componentProps: (values) => {
return {
disabled: values.status === 0
}
}
}
详情方法
通过 useDetailForm
返回的 detailFormApi
可以调用以下方法:
const [DetailForm, detailFormApi] = useDetailForm(schema)
// 设置详情状态
detailFormApi.setState({ labelPosition: 'top' })
// 获取详情状态
detailFormApi.getState()
完整示例
<template>
<div>
<el-radio-group v-model="labelPosition">
<el-radio-button value="left">左对齐</el-radio-button>
<el-radio-button value="right">右对齐</el-radio-button>
<el-radio-button value="top">顶部对齐</el-radio-button>
</el-radio-group>
<DetailForm
:model="detailData"
style="margin-top: 12px"
:border="true"
/>
</div>
</template>
<script setup lang="ts">
import { useDetailForm } from '@/components/form'
const labelPosition = ref<'left' | 'right' | 'top'>('right')
// 模拟详情数据
const detailData = ref({
name: '张三',
email: 'zhangsan@example.com',
status: 1,
gender: 1,
createTime: '2023-01-01 12:00:00',
avatar: 'https://example.com/avatar.jpg',
content: '<p>这是富文本内容</p>'
})
const schema = [
// 分割线
{
prop: 'divider-basic',
label: '',
labelWidth: '0px',
component: 'Divider',
colSpan: 24,
componentProps: {
title: '基本信息'
}
},
{
prop: 'name',
label: '姓名',
component: 'Input',
colSpan: 12
},
{
prop: 'email',
label: '邮箱',
component: 'Input',
colSpan: 12
},
{
prop: 'status',
label: '状态',
component: 'Select',
colSpan: 12,
componentProps: {
options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 }
]
}
},
{
prop: 'gender',
label: '性别',
component: 'RadioGroup',
colSpan: 12,
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 }
]
}
},
{
prop: 'createTime',
label: '创建时间',
component: 'DatePicker',
colSpan: 12
},
{
prop: 'avatar',
label: '头像',
component: 'Avatar',
colSpan: 12
},
{
prop: 'content',
label: '内容',
component: 'Editor',
colSpan: 24
}
]
const [DetailForm, detailFormApi] = useDetailForm({
labelPosition: labelPosition.value,
labelWidth: '100px',
schema: schema
})
// 监听标签位置变化
watch(() => labelPosition.value, (val) => {
detailFormApi.setState({ labelPosition: val })
})
</script>
注意事项
- 所有详情项必须包含
prop
和label
属性 - 详情组件主要用于数据展示,不支持数据编辑功能
- 使用远程数据组件时,确保 API 返回的数据格式符合要求
- 字典组件需要预先在系统中配置相应的字典数据
- 通过
componentProps
可以传递任何组件支持的属性 - 详情组件中的
ifDetail
用于控制字段在详情页面的显示 - 字典组件支持标签形式展示,
typeMap
和colorMap
配置样式