| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- <template>
- <fieldset class="g-fieldset app-table-details" :style="fieldsetStyle">
- <legend class="g-fieldset__legend" v-if="title">
- <slot name="title">
- {{ title }}
- </slot>
- </legend>
- <table class="app-table-details__table" cellspacing="0" cellpadding="0" :style="tableStyle">
- <tbody>
- <tr v-for="(items, i) in cellGroup" :key="i">
- <template v-for="(item, n) in items" :key="n">
- <th :style="labelStyle">
- <slot :name="item.prop + 'Label'">
- {{ item.formatLabel ? item.formatLabel(data[item.prop]) : item.label }}
- </slot>
- </th>
- <td :colspan="(items.length - 1) === n ? (column * 2 - items.length * 2) + 1 : 1"
- :style="valueStyle">
- <slot :name="item.prop" :value="data[item.prop]">
- {{ handleValue(item) }}
- </slot>
- </td>
- </template>
- </tr>
- </tbody>
- </table>
- <slot></slot>
- </fieldset>
- </template>
- <script lang="ts" setup>
- import { PropType, computed } from 'vue'
- import { handleNoneValue } from '@/filters'
- import { CellProp } from './types'
- const props = defineProps({
- title: String,
- data: {
- type: Object,
- default: () => ({})
- },
- cellProps: {
- type: Array as PropType<CellProp[]>,
- required: true
- },
- column: {
- type: Number,
- default: 1
- },
- width: {
- type: [String, Number],
- default: '100%'
- },
- // 标签宽度
- labelWidth: {
- type: Number,
- default: 0
- },
- // 标签对齐方式
- labelAlign: {
- type: String as PropType<'left' | 'center' | 'right'>,
- default: 'right'
- },
- // 边框大小
- borderWidth: {
- type: Number,
- default: 0
- },
- // 边框颜色
- borderColor: {
- type: String,
- default: '#213141'
- },
- })
- const cellGroup = computed(() => {
- // const result = []
- // let index = 0
- // // 一维数组转换成二维数组
- // while (index < props.cellProps.length) {
- // const rows = props.cellProps.slice(index, index += props.column)
- // result.push(rows)
- // }
- return props.cellProps.reduce<CellProp[][]>((pre, cur) => {
- if (cur.show === undefined || cur.show) {
- const rows = pre[pre.length - 1] // 获取上一组元素
- if (rows) {
- const cell = rows[rows.length - 1] // 获取最后一个元素
- if (cell.entireRow || cur.entireRow || rows.length === props.column) {
- pre[pre.length] = [cur]
- } else {
- rows.push(cur)
- }
- } else {
- pre[0] = [cur]
- }
- }
- return pre
- }, [])
- })
- const fieldsetStyle = computed(() => props.title ? {} : {
- borderWidth: 0,
- padding: 0
- })
- const tableStyle = computed(() => ({
- width: typeof props.width === 'number' ? props.width + 'px' : props.width
- }))
- const valueStyle = computed(() => ({
- borderWidth: props.borderWidth + 'px',
- borderColor: props.borderColor
- }))
- const labelStyle = computed(() => ({
- width: props.labelWidth ? props.labelWidth + 'px' : 'fit-content',
- textAlign: props.labelAlign,
- ...valueStyle.value
- }))
- const handleValue = (cell: CellProp) => {
- const value = props.data[cell.prop]
- const formattedValue = cell.formatValue ? cell.formatValue(value) : value
- if (Number.isFinite(formattedValue) && cell.decimal) {
- return formattedValue.toFixed(cell.decimal)
- }
- return handleNoneValue(formattedValue)
- }
- </script>
- <style lang="less">
- @import './index.less';
- </style>
|