组件效果
实现功能
- 栅格布局组件。根据屏幕尺寸(xs, md, lg),列宽会自动调整。
- 根据配置的字段显示不显示
- 动态设置label的宽度,可从当前项item.labelWidth或组件的labelWidth属性获取
- 利用getData(item)方法用于处理并返回每个配置项对应的数据,支持格式化、过滤等功能
代码片段
<template>
<el-row :gutter="14" style="width: 100%;" class="desc_contents">
<el-col
v-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).v
if(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 value
const 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>
总结
总之,这个组件提供了高度灵活的数据展示能力,允许用户通过配置来自定义展示哪些数据、如何格式化数据以及在不同屏幕尺寸下的布局,非常适合构建动态数据详情页面。