| | |
| | | <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"> |
| | | <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> <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="序号" width="60" align="center" fixed="left"> |
| | | <template #default="scope"> |
| | | {{ getRowIndex(scope.$index) }} |
| | | </template> |
| | | </el-table-column> |
| | | <template v-for="col in columns" :key="col.prop"> |
| | | <el-table-column v-bind="col" :show-overflow-tooltip="shouldShowTooltip(col, tableData)" |
| | | <el-table-column v-bind="col" |
| | | :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> |
| | | |
| | | <script setup> |
| | | import { defineEmits } from 'vue' |
| | | import { defineEmits, ref , defineProps, onMounted ,defineExpose, watch, nextTick} from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | const props = defineProps({ |
| | | // 最大宽度 |
| | |
| | | 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 |
| | | }, |
| | | // 当前页码 |
| | | currentPage: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | // 每页大小 |
| | | pageSize: { |
| | | type: Number, |
| | | default: 10 |
| | | } |
| | | }) |
| | | // 检查列是否需要显示tooltip |
| | | const shouldShowTooltip = (col, data) => { |
| | | // 如果列配置中明确设置了showOverflowTooltip,使用该设置 |
| | | if (col.hasOwnProperty('showOverflowTooltip')) { |
| | | return col.showOverflowTooltip; |
| | | } |
| | | // 如果没有prop,直接返回false |
| | | if (!col.prop) return false; |
| | | // 检查该列在所有数据中是否有非空值,默认显示tooltip |
| | | return data.some(row => row[col.prop] != null && row[col.prop] !== ''); |
| | | }; |
| | | const tableRef = ref(null) |
| | | |
| | | // 默认的格式化函数 |
| | | const defaultFormatter = (row, column, cellValue) => { |
| | |
| | | const handleExport = (row) => { |
| | | emit('export', row) |
| | | } |
| | | |
| | | // 计算分页序号 |
| | | const getRowIndex = (index) => { |
| | | return (props.currentPage - 1) * props.pageSize + index + 1; |
| | | }; |
| | | |
| | | // 正确的 toggleRowSelection 方法:针对单行 |
| | | const toggleRowSelection = (row, selected) => { |
| | | if (tableRef.value && row) { |
| | | tableRef.value.toggleRowSelection(row, selected); |
| | | } |
| | | }; |
| | | |
| | | // 批量设置行选中状态的方法 |
| | | const setRowsSelection = (rows, selected = true) => { |
| | | if (tableRef.value && Array.isArray(rows)) { |
| | | rows.forEach((row) => { |
| | | tableRef.value.toggleRowSelection(row, selected); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // 复选框默认选中状态 |
| | | const defaultSelection = ref([]) |
| | | // 设置默认选中状态 |
| | | const setDefaultSelection = () => { |
| | | if (!tableRef.value || !props.defaultSelectedIds.length || !props.tableData.length) { |
| | | return; |
| | | } |
| | | |
| | | |
| | | // 延迟执行,确保表格完全渲染 |
| | | 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(); |
| | | } |
| | | }, { |
| | | 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-tooltip) { |
| | | justify-content: center !important; |
| | | } |
| | | .el-table { |
| | | margin: 20px 0 !important; |
| | | } |