打造你的专属Vue组件:超实用“Descriptions展示组件开发”实战
组件效果
实现功能
- 栅格布局组件。根据屏幕尺寸(xs, md, lg),列宽会自动调整。
- 根据配置的字段显示不显示
- 动态设置label的宽度,可从当前项item.labelWidth或组件的labelWidth属性获取
- 利用getData(item)方法用于处理并返回每个配置项对应的数据,支持格式化、过滤等功能
代码片段
<template><el-row :gutter="14" style="width: 100%;" class="desc_contents"><el-colv-for="item in adjustedConfigs":key="item.prop":xs="item.col?.xs || 24":md="item.col?.md || 12":lg="item.col?.lg || 8"v-show="item.show !== false"class="desc_contents-item"><div class="label" :style="{ width: item.labelWidth || labelWidth || '110px' }"><slot :name="`${item.slotName}_label`">{{ item.label }}</slot></div><div class="data"><template #content><slot :name="`${item.slotName}_cont`">{{ getData(item) }}</slot></template><slot :name="`${item.slotName}_cont`">{{ getData(item) }}</slot></div></el-col></el-row>
</template><script setup>
import { computed } from 'vue'
defineOptions({name: 'HDescriptions'
})const props = defineProps({// 数据详情infoData: {type: Object,default: () => {}},// 配置项configs: {type: Array,default: () => []},// label宽度labelWidth: {type: String,default: '110px'}
})// 处理数据并返回
const getData = (item) => {const value = getPropByPath(props.infoData, item.prop).vif(value === null || value === undefined || value === '') return '/'if (item.formatter) return `${item.formatter(props.infoData)} ${item.unit || ''}` || '/'if (item.filters) {return constantEscape(value, item.filters.list || [], item.filters.key || 'value', item.filters.label || 'label_zh')}if (value || value === 0) return `${value} ${item.unit || ''}`return '/'
}
// 处理过滤的数据
const constantEscape = (value, list, key, label) => {if(!list?.length) return valueconst res = list.find((item: any) => {return item[key].toString() === value.toString()})if (res === undefined) return '/'return res && res[label]
}// 使用computed计算adjustedConfigs的生成
const adjustedConfigs = computed(() => {return props.configs.map((config) => {if (typeof config.show === 'function') {return { ...config, show: config.show(props.infoData) };}return config;});
});
</script><style lang="scss" scoped>
.desc_contents {&-item {margin-bottom: 6px;}:deep(.el-col){// padding: 5px 0;display: flex;font-size: 14px;.label {color: #909399;line-height: 140%;width: 86px;margin-right: 14px;flex-shrink: 0;}.data {line-height: 140%;color: #303133;flex: 1;width: 0;white-space: pre-wrap;.file {background: #f7faff;border: 1px solid rgba(28, 108, 249, 0.1);padding: 4px;display: flex;align-items: center;border-radius: 4px;& + .file {margin-top: 12px;}&-name {font-size: 14px;color: #333333;line-height: 20px;margin-bottom: 4px;}&-size {font-size: 12px;color: #999999;line-height: 20px;}&-icon {border: 1px solid #e1ecfe;border-radius: 4px;padding: 11px;margin-right: 10px;}}}}
}
</style>
总结
总之,这个组件提供了高度灵活的数据展示能力,允许用户通过配置来自定义展示哪些数据、如何格式化数据以及在不同屏幕尺寸下的布局,非常适合构建动态数据详情页面。