html部分:
<template>
<el-table :style="{ width: '100%' }" :header-cell-style="{ fontSize: '14px', background: '#cdecdf !important' }"
v-bind="$attrs" v-loading="loading" ref="tableRef" :data="tableData" :max-height="maxHeight" :row-key="rowKey"
:highlight-current-row="highlightCurrentRow" @row-click="handleRowClick" @select-all="selectAll"
@selection-change="handleSelectionChange" stripe>
<el-table-column v-for="item in columns" v-bind="$attrs" :key="item.prop"
:align="item.align ? item.align : 'center'" :prop="item.prop" :label="item.label"
:show-overflow-tooltip="item.showOverflowTooltip || true" :width="item.width" :fixed="item.fixed"
:type="item.type" :sortable="item.sortable" :selectable="item.selectableFn">
<!-- type 对应列的类型。 如果设置了selection则显示多选框; -->
<!-- 如果设置了 index 则显示该行的索引(从 1 开始计算); -->
<!-- 如果设置了 expand 则显示为一个可展开的按钮-->
<!-- selection / index / expand -->
<!-- 加斜线 -->
<template #header v-if="item.names && item.names.length > 0">
<div class="right">{{ item.names[0] }}</div>
<div class="left">
{{ item.names[1] }}
</div>
</template>
<template #header v-else-if="item.headerTitle">
<!-- {{ item.headerTitle }} -->
<slot :name="item.headerTitle">
</slot>
</template>
<template #default="{ row, column, $index }" v-if="item.type === 'index'">
{{ $index + 1 + (getIndex || 0) }}
</template>
<!-- 内容 -->
<template #default="{ row, column, $index }" v-if="item.function">
<div v-html="item.function(row)"></div>
</template>
<template #default="{ row, $index, column }" v-else="!item.type">
<!-- 具名作用域插槽 -->
<slot :name="item.prop" :slotProps="row" :index="$index" :column="column">
<!-- 默认内容,当父组件不传内容时默认显示该内容 -->
<span v-if="item.formatter">
{{ item.formatter(row[item.prop]) }}
</span>
<span v-else>
{{ row[item.prop] || "/" }}
</span>
</slot>
</template>
</el-table-column>
</el-table>
</template>
js部分
<script setup>
import { nextTick, toRefs, watch } from "vue";
const props = defineProps({
// 表格相关
tableData: {
type: Array,
default: [],
},
columns: {
type: Array,
default: [],
},
maxHeight: {
type: String,
default: "600px",
},
stripe: {
type: Boolean,
default: false,
},
rowKey: {
type: String,
default: "id",
},
highlightCurrentRow: {
type: Boolean,
default: true,
},
loading: {
type: Boolean,
default: false,
},
queryParams: {
type: Object,
default: () => ({})
}
});
let {
tableData,
columns,
height,
maxHeight,
stripe,
rowKey,
highlightCurrentRow,
loading,
arr,
} = toRefs(props);
const tableRef = ref(null);
const emit = defineEmits([
"rowClick",
"selectChange",
"changeTableData",
"update:pageSize",
"select-all",
]);
// 默认勾选
const toggleRowSelections = (rows) => {
nextTick(() => {
rows.forEach((row) => {
if (tableRef.value) {
tableRef.value.toggleRowSelection(row, true);
}
});
});
};
// 单行选中
const setCurrent = (row) => {
nextTick(() => {
if (tableRef.value) {
tableRef.value.setCurrentRow(row)
}
});
}
// 清除所有选中
const clearSelection = () => {
tableRef.value.clearSelection();
};
// 当某一行被点击时会触发该事件
const handleRowClick = (row, column, event) => {
emit("rowClick", { row, column, event });
};
// 当选择项发生变化时会触发该事件
const handleSelectionChange = (selection) => {
emit("selectChange", selection);
};
// 当某一行被点击时会触发该事件
const selectAll = (val) => {
emit("select-all", val);
};
const getIndex = computed(() => {
return ((props.queryParams.pageNum - 1) * props.queryParams.pageSize) || 0;
});
// 暴露方法给父组件调用
defineExpose({ clearSelection, toggleRowSelections, setCurrent,tableRef });
style部分
<style lang="scss" scoped>
.left {
text-align: right;
position: relative;
padding-left: 10px;
}
.left::after {
content: "";
width: 100%;
height: 0px;
position: absolute;
border-bottom: 1px solid #ccc;
top: 0;
left: 0;
transform: rotate(-12deg);
}
.right {
text-align: left;
padding-right: 10px;
}
:deep(.el-table__cell) {
border: 1px solid #ebeef5 !important;
}
/* 选中行样式 */
::v-deep(.el-table__body tr.current-row > td) {
background-color: #fffff5 !important;
border-top: 1px solid #facd91 !important;
border-bottom: 1px solid #facd91 !important;
}
</style>