From 7c86b549b27bd54f6bd5de81c13f8242f91c87ff Mon Sep 17 00:00:00 2001 From: 张诺 <zhang_12370@163.com> Date: 星期一, 16 六月 2025 18:03:27 +0800 Subject: [PATCH] 优化文件上传组件及表格显示 --- src/components/Table/ETable.vue | 436 ++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 274 insertions(+), 162 deletions(-) diff --git a/src/components/Table/ETable.vue b/src/components/Table/ETable.vue index 88c6f57..13d2dda 100644 --- a/src/components/Table/ETable.vue +++ b/src/components/Table/ETable.vue @@ -1,177 +1,277 @@ -<template> - <el-table - v-loading="loading" - :data="tableData" - style="width: 100%" - :border="border" - :show-selection="showSelection" - :max-height="maxHeight" - @selection-change="handleSelectionChange" -<<<<<<< HEAD -======= - @row-click="handleRowClick" - @row-dblclick="handleRowDblClick" - @cell-click="handleCellClick" - :max-width="maxWidth" - @export="handleExport" ->>>>>>> master - > - <el-table-column v-if="showSelection" type="selection" width="55" align="center" /> - <el-table-column v-if="showIndex" label="搴忓彿" type="index" width="60" align="center" /> - <template v-for="col in columns" :key="col.prop"> - <el-table-column - v-bind="col" - :show-overflow-tooltip="col.showOverflowTooltip !== false" - > - <template v-if="col.slot" #default> - <slot></slot> - </template> - </el-table-column> - </template> - <!-- 鎿嶄綔鍒� --> - <el-table-column v-if="showOperations" :label="operationsLabel" :width="operationsWidth" fixed="right"> - <template #default="scope"> - <slot name="operations" :row="scope.row"> - <el-button - v-if="operations.includes('edit')" - link - type="primary" - size="small" - @click="handleEdit(scope.row)" - >缂栬緫</el-button> - <el-button - v-if="operations.includes('delete')" - link - type="danger" - size="small" - @click="handleDelete(scope.row)" - >鍒犻櫎</el-button> - </slot> +<template> <el-table + v-loading="loading" + :data="tableData" + :border="border" + :show-selection="showSelection" + :max-height="maxHeight" + :header-cell-style="{ background: '#EBEEF5', color: '#3D3D3D' }" + @selection-change="handleSelectionChange" + @row-click="handleRowClick" + @row-dblclick="handleRowDblClick" + @cell-click="handleCellClick" + :max-width="maxWidth" + @export="handleExport" + :default-selection="defaultSelection" + :show-overflow-tooltip="showOverflowTooltip" + ref="tableRef" + :row-key="rowKey" + style="width: 100%" + > + <el-table-column v-if="showSelection" type="selection" width="55" align="center" /> + <el-table-column v-if="showIndex" label="搴忓彿" type="index" width="60" align="center" /> + <template v-for="col in columns" :key="col.prop"> + <el-table-column v-bind="col" :show-overflow-tooltip="shouldShowTooltip(col, tableData)" + :formatter="col.formatter || defaultFormatter" align="center"> + <template v-if="col.slot" #default="scope"> + <slot :name="col.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot> </template> </el-table-column> - </el-table> - </template> + </template> + <!-- 鎿嶄綔鍒� --> + <el-table-column v-if="showOperations" :label="operationsLabel" :width="operationsWidth" fixed="right" align="center"> + <template #default="scope"> + <slot name="operations" :row="scope.row"> + <el-button v-if="operations.includes('edit')" link type="primary" size="small" + @click="handleEdit(scope.row)">缂栬緫</el-button> + <!-- <el-button--> + <!-- v-if="operations.includes('delete')"--> + <!-- link--> + <!-- type="danger"--> + <!-- size="small"--> + <!-- @click="handleDelete(scope.row)"--> + <!-- >鍒犻櫎</el-button>--> + </slot> + </template> + </el-table-column> + </el-table> +</template> <script setup> - import { defineEmits } from 'vue' - import { ElMessage, ElMessageBox } from 'element-plus' +import { defineEmits, ref , defineProps, onMounted ,defineExpose, watch, nextTick} from 'vue' +import { ElMessage, ElMessageBox } from 'element-plus' +const props = defineProps({ + // 鏈�澶у搴� + maxWidth: { + type: [String, Number], + default: 'auto' + }, + handleCellClick: { + type: Function, + default: () => { } + }, + handleRowClick: { + type: Function, + default: () => { } + }, + handleExport: { + type: Function, + default: () => { } + }, + handleRowDblClick: { + type: Function, + default: () => { } + }, + // 楂樺害 + maxHeight: { + type: [String, Number], + default: 'auto' + }, + // 鍔犺浇鐘舵�� + loading: { + type: Boolean, + default: false + }, + // border + border: { + type: Boolean, + default: false + }, + // 琛ㄦ牸鏁版嵁 + tableData: { + type: Array, + default: () => [] + }, + // 鏄惁鏄剧ず閫夋嫨鍒� + showSelection: { + type: Boolean, + default: true + }, + // 鏄惁鏄剧ず搴忓彿鍒� + showIndex: { + type: Boolean, + default: true + }, + // 鍒楅厤缃� + columns: { + type: Array, + default: () => [] + }, + // 鏄惁鏄剧ず鎿嶄綔鍒� + showOperations: { + type: Boolean, + default: true + }, + // 鎿嶄綔鍒楁爣绛� + operationsLabel: { + type: String, + default: '鎿嶄綔' + }, + // 鎿嶄綔鍒楀搴� + operationsWidth: { + type: [String, Number], + default: 100 + }, + // 鏄剧ず鍝簺鎿嶄綔鎸夐挳 + operations: { + type: Array, + default: () => ['edit', 'delete', 'export'] + }, // 鍒犻櫎纭淇℃伅 + deleteConfirmText: { + type: String, + default: '纭鍒犻櫎璇ヨ褰曪紵' + }, + // 榛樿閫変腑鐨勮 ID 鏁扮粍 + defaultSelectedIds: { + type: Array, + default: () => [] + }, + // 琛屽敮涓�鏍囪瘑瀛楁鍚嶏紙榛樿涓� id锛� + rowKey: { + type: String, + default: 'id' + }, + showOverflowTooltip: { + type: Boolean, + default: true + } +}) +const tableRef = ref(null) +// 妫�鏌ュ垪鏄惁闇�瑕佹樉绀簍ooltip +const shouldShowTooltip = (col, data) => { + // 濡傛灉鍒楅厤缃腑鏄庣‘璁剧疆浜唖howOverflowTooltip锛屼娇鐢ㄨ璁剧疆 + if (col.hasOwnProperty('showOverflowTooltip')) { + return col.showOverflowTooltip; + } + // 濡傛灉娌℃湁prop锛岀洿鎺ヨ繑鍥瀎alse + if (!col.prop) return false; + // 妫�鏌ヨ鍒楀湪鎵�鏈夋暟鎹腑鏄惁鏈夐潪绌哄�硷紝榛樿鏄剧ずtooltip + return data.some(row => row[col.prop] != null && row[col.prop] !== ''); +}; - const props = defineProps({ -<<<<<<< HEAD -======= - // 鏈�澶у搴� - maxWidth: { - type: [String, Number], - default: 'auto' - }, - handleCellClick: { - type: Function, - default: () => {} - }, - handleRowClick: { - type: Function, - default: () => {} - }, - handleExport: { - type: Function, - default: () => {} - }, - handleRowDblClick: { - type: Function, - default: () => {} - }, ->>>>>>> master - // 楂樺害 - maxHeight: { - type: [String, Number], - default: 'auto' - }, - // 鍔犺浇鐘舵�� - loading: { - type: Boolean, - default: false - }, - // border - border: { - type: Boolean, - default: false - }, - // 琛ㄦ牸鏁版嵁 - tableData: { - type: Array, - default: () => [] - }, - // 鏄惁鏄剧ず閫夋嫨鍒� - showSelection: { - type: Boolean, - default: true - }, - // 鏄惁鏄剧ず搴忓彿鍒� - showIndex: { - type: Boolean, - default: true - }, - // 鍒楅厤缃� - columns: { - type: Array, - default: () => [] - }, - // 鏄惁鏄剧ず鎿嶄綔鍒� - showOperations: { - type: Boolean, - default: true - }, - // 鎿嶄綔鍒楁爣绛� - operationsLabel: { - type: String, - default: '鎿嶄綔' - }, - // 鎿嶄綔鍒楀搴� - operationsWidth: { - type: [String, Number], - default: 160 - }, - // 鏄剧ず鍝簺鎿嶄綔鎸夐挳 - operations: { - type: Array, - default: () => ['edit', 'delete', 'export'] - }, - // 鍒犻櫎纭淇℃伅 - deleteConfirmText: { - type: String, - default: '纭鍒犻櫎璇ヨ褰曪紵' +// 榛樿鐨勬牸寮忓寲鍑芥暟 +const defaultFormatter = (row, column, cellValue) => { + return cellValue == null || cellValue === '' || cellValue === 0 ? '--' : cellValue; +}; + +// 澶勭悊閫夋嫨鍙樺寲銆佺紪杈戙�佸垹闄ゅ拰瀵煎嚭鎿嶄綔 +const emit = defineEmits(['selection-change', 'edit', 'delete', 'export']) +const handleSelectionChange = (selection) => { + emit('selection-change', selection) +} +const handleEdit = (row) => { + emit('edit', row) +} +const handleDelete = (row) => { + ElMessageBox.confirm( + props.deleteConfirmText, + '璀﹀憡', + { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' } - }) - const emit = defineEmits(['selection-change', 'edit', 'delete', 'export']) - const handleSelectionChange = (selection) => { - emit('selection-change', selection) + ).then(() => { + emit('delete', row) + }).catch(() => { }) +} + +const handleExport = (row) => { + emit('export', row) +} + +// 姝g‘鐨� toggleRowSelection 鏂规硶锛氶拡瀵瑰崟琛� +const toggleRowSelection = (row, selected) => { + if (tableRef.value && row) { + tableRef.value.toggleRowSelection(row, selected); } - const handleEdit = (row) => { - emit('edit', row) +}; + +// 鎵归噺璁剧疆琛岄�変腑鐘舵�佺殑鏂规硶 +const setRowsSelection = (rows, selected = true) => { + if (tableRef.value && Array.isArray(rows)) { + rows.forEach((row) => { + tableRef.value.toggleRowSelection(row, selected); + }); } - const handleDelete = (row) => { - ElMessageBox.confirm( - props.deleteConfirmText, - '璀﹀憡', - { - confirmButtonText: '纭畾', - cancelButtonText: '鍙栨秷', - type: 'warning' - } - ).then(() => { - emit('delete', row) - }).catch(() => {}) +}; + +// 澶嶉�夋榛樿閫変腑鐘舵�� +const defaultSelection = ref([]) +// 璁剧疆榛樿閫変腑鐘舵�� +const setDefaultSelection = () => { + if (!tableRef.value || !props.defaultSelectedIds.length || !props.tableData.length) { + return; } - const handleExport = (row) => { - emit('export', row) + + // 寤惰繜鎵ц锛岀‘淇濊〃鏍煎畬鍏ㄦ覆鏌� + nextTick(() => { + setTimeout(() => { + try { + tableRef.value.clearSelection(); + const rowsToSelect = props.tableData.filter(row => { + const rowId = row[props.rowKey]; + return props.defaultSelectedIds.includes(rowId); + }); + rowsToSelect.forEach(row => { + tableRef.value.toggleRowSelection(row, true); + }); + } catch (error) { + } + }, 100); + }); +}; + +// 鐩戝惉鏁版嵁鍙樺寲锛岃嚜鍔ㄨ缃粯璁ら�変腑 +watch(() => [props.tableData, props.defaultSelectedIds], () => { + if (props.tableData.length > 0 && props.defaultSelectedIds.length > 0) { + setDefaultSelection(); } - </script> +}, { + deep: true, + immediate: true +}); + +// 缁勪欢鎸傝浇鍚庤缃粯璁ら�変腑 +onMounted(() => { + if (props.defaultSelectedIds.length > 0) { + setDefaultSelection(); + } +}); + +// 鏆撮湶 el-table 鐨勫疄渚嬪拰甯哥敤鏂规硶 +defineExpose({ + // 鍗曡閫変腑/鍙栨秷閫変腑 + toggleRowSelection, + // 鎵归噺璁剧疆琛岄�変腑鐘舵�� + setRowsSelection, + // 鏍规嵁ID鏁扮粍閫変腑琛� + setDefaultSelection, + // 娓呴櫎鎵�鏈夐�変腑 + clearSelection: () => tableRef.value?.clearSelection(), + // 鑾峰彇閫変腑鐨勮 + getSelectionRows: () => tableRef.value?.getSelectionRows() || [], + // 璁剧疆褰撳墠琛� + setCurrentRow: (row) => tableRef.value?.setCurrentRow(row), + // 鑾峰彇琛ㄦ牸瀹炰緥锛堝闇�鐩存帴鎿嶄綔锛� + getTableRef: () => tableRef.value +}); + +</script> <style scoped> - :deep(.el-table) { - margin-bottom: 20px; - overflow-x: auto; +.el-table { + margin: 20px 0 !important; } :deep(.el-table th) { @@ -185,4 +285,16 @@ overflow-x: auto; } } - </style> \ No newline at end of file + + /* 鏀寔鍦板潃鍒楁崲琛屾樉绀� */ + :deep(.el-table .cell) { + white-space: normal !important; + word-break: break-all; + line-height: 1.4; + } + + /* 涓哄湴鍧�鍒楄缃渶灏忛珮搴︿互瀹圭撼澶氳鏂囨湰 */ + :deep(.el-table td) { + padding: 8px 0; + } +</style> \ No newline at end of file -- Gitblit v1.9.3