<template>
<!-- 是否显示表头的全选 -->
<div :class="{isSingle:props.isSingle}">
<el-table
:header-cell-style="props.headerCellStyle"
:header-row-style="props.headerRowStyle"
:data="props.tableData"
:max-height="props.maxHeight"
:size="props.size"
ref="tableRef"
style="width: 100%"
:highlight-current-row="props.highlightCurrentRow"
@current-change="changeCurrent"
@selection-change="changeSelect"
@select="changeSelectTap"
@select-all="changeSelectAll"
:row-key="props.rowKey"
:tree-props="props.treeProps||treeProps"
>
<!-- 是否开启多选功能 -->
<el-table-column v-if="props.isSelect" :reserve-selection="true" type="selection" width="50"/>
<!-- 遍历表头数据 -->
<template v-for="(item, index) in props.header">
<el-table-column
:key="index"
:align="item.align || 'center'"
:sortable="item.sortable"
:width="item.width"
:min-width="item.minWidth"
:label="item.label"
:prop="item.prop"
:fixed="item.fixed"
v-if="item.isShow == false ? false : true"
show-overflow-tooltip
>
<!-- 自定义行slot -->
<template v-if="item.isCustom" #default="scope">
<slot :name="item.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot>
</template>
</el-table-column>
</template>
</el-table>
<!-- 分页,传了分页数据就会展示 -->
<div v-if="page" class="mt15 flex-center">
<el-pagination
:currentPage="props.page?.pageIndex"
:page-size="props.page?.pageSize"
:page-sizes="[10, 20, 30]"
layout="sizes, prev, pager, next, jumper"
:total="props.page?.total"
:background="true"
:hide-on-single-page="false"
@size-change="changeSize"
@current-change="changePage"
>
</el-pagination>
</div>
</div>
</template>
<script lang="ts" setup>
import {ref} from "vue";
import { ElTable,ElPagination } from "element-plus";
const tableRef=ref();
interface Header {
label: string;
prop?: string;
width?: string | number;
minWidth?: string | number;
sortable?: boolean;
align?: string;
isCustom?: boolean;
fixed?: string;
isShow?: boolean;
}
interface Page {
total?: number;
pageSize?: number;
pageIndex?: number;
background?: boolean;
}
interface Props {
tableData: Array<any>;
page?: Page;
isSelect?: boolean;
isSingle?: boolean;
size?: 'large' | 'default' | 'small';
header: Array<Header>;
maxHeight?: string | number;
headerRowStyle?: Function | object;
headerCellStyle?: Function | object;
highlightCurrentRow?: boolean;
rowKey?: string,
treeProps?: Function |object
}
const treeProps={ children: 'children', hasChildren: 'hasChildren' }
const props = withDefaults(defineProps<Props>(), {
isSelect: false,
isOperation: true,
size: 'default',
highlightCurrentRow: false,
rowKey: 'id',
isSingle:false
});
const changeSize = (size: number) => {
emit('changeSize', size);
}
const changePage = (page: number) => {
emit('changePage', page);
}
const changeCurrent = (currentRow: any, oldCurrentRow: any) => {
emit('changeCurrent', {currentRow, oldCurrentRow})
}
const changeSelect = (val: any) => {
emit('onSelect', val)
}
const changeSelectAll = (val: any) => {
emit('onSelectAll', val)
}
const changeSelectTap = (val: any,row:any) => {
emit('onSelectTap', val,row)
}
defineExpose({ tableRef})
const emit = defineEmits(['changeSize', 'changePage', 'changeCurrent', 'onSelect','onSelectTap','onSelectAll']);
</script>
<style lang="scss" scoped>
.isSingle{
:deep(*){
.el-table__header{
.el-checkbox{
visibility: hidden;
}
}
}
}
</style>
<template>
<MyTable
ref="tableRef"
:page="tableData.page"
:isSelect="true"
:rowKey="'id'"
@changeSize="(size) => changeSize(size)"
@changePage="(page) => changePage(page)"
:header="header"
:tableData="
tableData.data.slice(
(tableData.page.pageIndex - 1) * tableData.page.pageSize,
tableData.page.pageIndex * tableData.page.pageSize
)
"
@onSelectTap="changeSelectTap"
@onSelectAll="changeSelectAll"
>
<template v-slot:sex="scope">
{{ scope.row.sex == "0" ? "男" : "女" }}
</template>
<template v-slot:operation="scope">
<el-button @click="handelEdit(scope.row)">编辑</el-button>
<el-button @click="handelDel(scope.row)">删除</el-button>
</template>
</MyTable>
</template>
<script lang="ts" setup>
import MyTable from "./components/myTable.vue";
import { ref, reactive, onMounted } from "vue";
const tableRef = ref();
const header = reactive([
{
label: "姓名",
prop: "name",
},
{
label: "性别",
prop: "sex",
isCustom: true,
},
{
label: "年龄",
prop: "age",
},
{
label: "操作",
prop: "operation",
isCustom: true,
fixed: "right",
align: "center",
width: 200,
},
]);
const tableData = reactive({
data: [],
searchForm: {},
page: {
pageIndex: 1,
pageSize: 10,
total: 500,
},
});
const handelEdit = (val) => {
console.log("编辑");
};
const handelDel = (val) => {
console.log("删除");
};
onMounted(() => {
setTimeout(() => {
for (let i = 0; i < 500; i++) {
let obj = {
id:i,
name: `c${i + 1}`,
sex: parseInt(String(Math.random() * 2)),
age: Math.round(Math.random() * 100),
};
tableData.data.push(obj);
}
}, 1500);
});
</script>
<style scoped></style>
const ids = ref('');
const changeSelectTap = (val: any) => {
ids.value = val.map((v: any) => v.id).join(',');
};
const isSelectAll = ref(false);
const changeSelectAll = (val: any) => {
if (!isSelectAll.value) {
isSelectAll.value = true;
ids.value = tableData.data.map((v: any) => v.id).join(',');
console.log(ids.value);
} else {
ids.value = '';
isSelectAll.value = false;
console.log(ids.value);
}
};
const changeSize = (size: any) => {
tableData.page.pageIndex = 1;
tableData.page.pageSize = size;
let selectData = ids.value.split(",");
tableData.data.forEach((v: any) => {
let index = selectData.findIndex((t) => {
return v.id == t;
});
tableRef.value.tableRef.toggleRowSelection(v, index != -1);
});
};
const changePage = (page: any) => {
tableData.page.pageIndex = page;
let selectData = ids.value.split(",");
tableData.data.forEach((v: any) => {
let index = selectData.findIndex((t) => {
return v.id === t;
});
tableRef.value.tableRef.toggleRowSelection(v, index != -1);
});
};