71 lines
2.1 KiB
Vue
71 lines
2.1 KiB
Vue
<template>
|
|
<div class="table-container">
|
|
<el-table :data="tableData" :row-key="rowKey" :tree-props="treeProps" :border="border"
|
|
:highlight-current-row="highlightCurrentRow" v-bind="$attrs" @row-click="handleRowClick">
|
|
<!-- 动态表头列 -->
|
|
<template v-for="(column, index) in columns" :key="index">
|
|
<el-table-column v-if="!column.slotName" :prop="column.prop" :label="column.label" :width="column.width"
|
|
:align="column.align || 'left'" :sortable="column.sortable" />
|
|
|
|
<!-- 具名插槽列 -->
|
|
<el-table-column v-else :label="column.label" :width="column.width" :align="column.align || 'left'">
|
|
<template #default="{ row }">
|
|
<slot :name="column.slotName" :row="row" />
|
|
</template>
|
|
</el-table-column>
|
|
</template>
|
|
</el-table>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
// 定义表格列配置接口
|
|
interface TableColumn {
|
|
prop?: string
|
|
label: string
|
|
width?: string | number
|
|
align?: 'left' | 'center' | 'right'
|
|
slotName?: string // 具名插槽名称
|
|
sortable?: boolean // 是否可排序
|
|
}
|
|
|
|
// 定义表格组件属性接口
|
|
interface Props {
|
|
tableData: any[]
|
|
rowKey?: string
|
|
treeProps?: {
|
|
children: string
|
|
}
|
|
columns?: TableColumn[],
|
|
border?: boolean // 是否显示边框
|
|
highlightCurrentRow?: boolean // 是否高亮当前行
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
border: true,
|
|
highlightCurrentRow: true,
|
|
})
|
|
|
|
// 定义组件抛出的事件
|
|
const emit = defineEmits<{
|
|
(e: 'row-click', row: any): void // 保留原有行点击事件
|
|
}>()
|
|
|
|
/**
|
|
* 处理行点击事件(兼容原有逻辑)
|
|
*/
|
|
const handleRowClick = (row: any) => {
|
|
// 增加空值保护,避免传递 null 给父组件
|
|
if (!row) return
|
|
emit('row-click', row)
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.table-container {
|
|
max-width: calc(100vw - 200px);
|
|
max-height: calc(100vh - 180px);
|
|
overflow: auto;
|
|
}
|
|
</style>
|