UseElDescriptions - 描述列表
组件介绍
UseElDescriptions 是基于 Element Plus 的 ElDescriptions 二次封装的描述列表组件,专注于为详情信息展示场景提供开箱即用的配置化渲染、空值兜底、数据格式化能力,同时标准化扩展配置项管理,完整兼容原生 ElDescriptions 核心属性与插槽,可直接替换原生 ElDescriptions 使用,大幅降低详情页、信息卡片场景的重复模板代码编写成本。
核心能力
- 开箱即用的配置化渲染能力
内置描述项配置(columns),支持通过数组配置自动生成所有描述项,无需手写大量重复的 el-descriptions-item 标签,配置项支持标签名、字段名、跨列数、标签宽度、自定义渲染等能力,未配置时自动透传原生子元素,兼顾配置化效率与自定义灵活性。
- 标准化的空值兜底能力
内置全局空值处理逻辑,自动识别 null/undefined/ 空字符串等无效值,统一展示配置的空值占位符(默认 “-”),支持自定义空值展示内容,无需每个描述项单独编写空值判断逻辑,彻底解决详情页空值展示不统一的问题。
- 灵活的配置优先级管理
所有扩展配置遵循「组件局部配置 > 全局默认配置 > 内置默认值」优先级规则,组件传入的 extConfig 优先覆盖 defaultExtConfig 中的默认配置(如默认列数 2、标签宽度 100px、标签对齐方式 right、空值占位符 “-”),未配置时自动兜底,兼顾项目全局展示规范与页面局部定制需求。
- 完善的数据格式化能力
内置常用场景数据格式化器:支持日期自动格式化(兼容时间戳 / 日期字符串,默认格式 “YYYY-MM-DD HH:mm:ss”)、金额千分位格式化、枚举状态自动映射标签、长文本自动省略 + 悬浮 tooltip 展示,同时支持自定义格式化函数,覆盖绝大多数详情字段展示需求。
- 原生描述列表完全兼容
基于 ElDescriptions 封装,完整保留原生 border、column、direction、size、title 等核心属性,标题插槽、操作区插槽、默认插槽完全透传,所有 el-descriptions-item 的原生属性都可通过 columns 配置项透传,可直接替换原生 ElDescriptions 使用,无迁移成本,同时补充原生组件缺失的配置化渲染、统一空值处理能力。
- 样式兼容与问题修复
内置样式修复逻辑:解决 ElDescriptions 在 el-drawer/el-dialog 等弹窗容器内使用时边框样式被覆盖的问题,修复长文本无省略导致的布局错位问题,统一不同尺寸下的内边距与标签对齐基线,修复低分辨率下列数自适应错乱问题,保证组件在不同容器、不同屏幕尺寸下的样式一致性。
- 扩展配置标准化
通过 ExtConfig 接口标准化列配置、空值处理、格式化规则、加载状态、空状态等扩展配置项,提供 defaultExtConfig 全局默认扩展配置,业务侧可全局统一覆盖配置项(如默认日期格式、空值占位符、默认列数),保证项目内所有详情展示场景的配置规范统一。
- 安全的生命周期管理
组件挂载时自动绑定窗口 resize 事件,支持响应式自动适配列数;卸载时自动移除事件监听、清除定时器与 tooltip 实例,避免内存泄漏,保证组件在弹窗 / 抽屉内嵌、动态 v-if 渲染等场景下的稳定性。
使用
Props
import type { PropType } from 'vue'
import type { ConfigColumn } from './types'
import type { DictMap, DictProps } from '@/types'
import type { RenderConfig } from '@/types'
/**
* 组件props
*/
export default {
/**
* 配置项 必传
*/
configs: {
type: Array as PropType<ConfigColumn[]>,
required: true
},
/**
* 表单模型 必传
*/
formModel: {
type: Object as PropType<Record<string, any>>,
required: true
},
/**
* 是否使用渲染器 默认否
*/
useRender: {
type: [Boolean, Object] as PropType<boolean | RenderConfig>,
default: false
},
/**
* 字典映射 数据结构为{ configs[][label | useDict | useDict.key]: Array<{ label: string, value: any }> }
*/
dictMap: {
type: Object as PropType<DictMap>,
default: () => ({})
},
/**
* 字典属性 默认为{ value: 'value', label: 'label', children: 'children' },可通过全局配置进行设置,为适配全局配置此处不再设置默认值
*/
dictProps: {
type: Object as PropType<DictProps>,
default: () => ({})
},
/**
* 一行 Descriptions Item 的数量 默认2
*/
column: {
type: Number,
default: 2
},
/**
* 是否带有边框 默认是
*/
border: {
type: Boolean,
default: true
},
/**
* 每一列的标签宽度
*/
labelWidth: {
type: [String, Number],
default: '25%'
},
/**
* 是否让标题居中并且header具有背景色 默认否
*/
useTitleCenterWithBg: {
type: Boolean,
default: false
},
/**
* 标签包裹类名
*/
labelClass: {
type: String,
default: ''
},
/**
* 默认内容包裹类名
*/
defaultClass: {
type: String,
default: ''
}
}Types
import type { Component, ExtractPropTypes } from 'vue'
import type { EditAttrs, RenderConfig, UseDict } from '@/types'
import componentProps from './props'
/**
* props类型
*/
export type Props = ExtractPropTypes<typeof componentProps>
/**
* emits类型
*/
export type Emits = {
// dictKeys事件
(e: 'onDictKeys', value?: string[]): void
}
/**
* 组件配置接口
*/
export interface ComponentConfig {
is: Component
attrs?: EditAttrs
}
/**
* 配置列接口
*/
export interface ConfigColumn {
label: string
prop: string
span?: number
useDict?: boolean | string | UseDict
defaultClass?: string
slot?: boolean | string
componentConfig?: ComponentConfig
renderConfig?: RenderConfig
}