张诺
6 天以前 dd159ea51a7a77bd8cc00c70c0e900f472fb3395
src/components/Table/ETable.vue
@@ -1,178 +1,169 @@
<template>
    <el-table
      v-loading="loading"
      :data="tableData"
      style="width: 100%"
      :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 v-for="col in columns" :key="col.prop">
        <el-table-column
          v-bind="col"
          :show-overflow-tooltip="shouldShowTooltip(col, tableData)"
          :formatter="(row, column, cellValue) => cellValue == null || cellValue === '' ? '--' : cellValue"
        >
          <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" 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>
  <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
      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>
          <slot></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'
  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: '确认删除该记录?'
    }
  })
  // 检查列是否需要显示tooltip
  const shouldShowTooltip = (col, data) => {
import { defineEmits } 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: '确认删除该记录?'
  }
})
// 检查列是否需要显示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 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'
      }
    ).then(() => {
      emit('delete', row)
    }).catch(() => {})
  }
  const handleExport = (row) => {
    emit('export', row)
  }
  </script>
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'
    }
  ).then(() => {
    emit('delete', row)
  }).catch(() => { })
}
const handleExport = (row) => {
  emit('export', row)
}
</script>
  
  <style scoped>
  .el-table {
.el-table {
    margin: 20px 0 !important;
  }
  
@@ -187,4 +178,16 @@
      overflow-x: auto;
    }
  }
  </style>
  /* 支持地址列换行显示 */
  :deep(.el-table .cell) {
    white-space: normal !important;
    word-break: break-all;
    line-height: 1.4;
  }
  /* 为地址列设置最小高度以容纳多行文本 */
  :deep(.el-table td) {
    padding: 8px 0;
  }
</style>