Skip to content

UseElDescriptions - 描述列表

组件介绍

UseElDescriptions 是基于 Element Plus 的 ElDescriptions 二次封装的描述列表组件,专注于为详情信息展示场景提供开箱即用的配置化渲染、空值兜底、数据格式化能力,同时标准化扩展配置项管理,完整兼容原生 ElDescriptions 核心属性与插槽,可直接替换原生 ElDescriptions 使用,大幅降低详情页、信息卡片场景的重复模板代码编写成本。

核心能力

  1. 开箱即用的配置化渲染能力

内置描述项配置(columns),支持通过数组配置自动生成所有描述项,无需手写大量重复的 el-descriptions-item 标签,配置项支持标签名、字段名、跨列数、标签宽度、自定义渲染等能力,未配置时自动透传原生子元素,兼顾配置化效率与自定义灵活性。

  1. 标准化的空值兜底能力

内置全局空值处理逻辑,自动识别 null/undefined/ 空字符串等无效值,统一展示配置的空值占位符(默认 “-”),支持自定义空值展示内容,无需每个描述项单独编写空值判断逻辑,彻底解决详情页空值展示不统一的问题。

  1. 灵活的配置优先级管理

所有扩展配置遵循「组件局部配置 > 全局默认配置 > 内置默认值」优先级规则,组件传入的 extConfig 优先覆盖 defaultExtConfig 中的默认配置(如默认列数 2、标签宽度 100px、标签对齐方式 right、空值占位符 “-”),未配置时自动兜底,兼顾项目全局展示规范与页面局部定制需求。

  1. 完善的数据格式化能力

内置常用场景数据格式化器:支持日期自动格式化(兼容时间戳 / 日期字符串,默认格式 “YYYY-MM-DD HH:mm:ss”)、金额千分位格式化、枚举状态自动映射标签、长文本自动省略 + 悬浮 tooltip 展示,同时支持自定义格式化函数,覆盖绝大多数详情字段展示需求。

  1. 原生描述列表完全兼容

基于 ElDescriptions 封装,完整保留原生 border、column、direction、size、title 等核心属性,标题插槽、操作区插槽、默认插槽完全透传,所有 el-descriptions-item 的原生属性都可通过 columns 配置项透传,可直接替换原生 ElDescriptions 使用,无迁移成本,同时补充原生组件缺失的配置化渲染、统一空值处理能力。

  1. 样式兼容与问题修复

内置样式修复逻辑:解决 ElDescriptions 在 el-drawer/el-dialog 等弹窗容器内使用时边框样式被覆盖的问题,修复长文本无省略导致的布局错位问题,统一不同尺寸下的内边距与标签对齐基线,修复低分辨率下列数自适应错乱问题,保证组件在不同容器、不同屏幕尺寸下的样式一致性。

  1. 扩展配置标准化

通过 ExtConfig 接口标准化列配置、空值处理、格式化规则、加载状态、空状态等扩展配置项,提供 defaultExtConfig 全局默认扩展配置,业务侧可全局统一覆盖配置项(如默认日期格式、空值占位符、默认列数),保证项目内所有详情展示场景的配置规范统一。

  1. 安全的生命周期管理

组件挂载时自动绑定窗口 resize 事件,支持响应式自动适配列数;卸载时自动移除事件监听、清除定时器与 tooltip 实例,避免内存泄漏,保证组件在弹窗 / 抽屉内嵌、动态 v-if 渲染等场景下的稳定性。

使用

UseElDescriptions

Props

ts
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

ts
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
}

基于 MIT 许可发布