<template>
<div ref="tableWrapRef" :class="props.bordered ? '' : 'border_task'">
<ConfigProvider>
<template #renderEmpty>
<div class="empty">
<a-empty :image="imgEmty"> </a-empty>
</div>
</template>
<a-table
class="ant-table-striped"
:sticky="props.sticky"
:dataSource="props.dataSource"
:columns="props.columns"
:pagination="false"
:showSorterTooltip="false"
:scroll="{ x: false }"
:bordered="props.bordered"
:expandIcon="props.expandIcon"
:indentSize="20"
:loading="props.loading"
:customRow="props.customRow"
:rowClassName="props.rowClassName ? props.rowClassName : (_, index) => (index % 2 === 1 ? 'table-striped' : null)"
:row-key="props.rowKey || (r => r)"
:row-selection="
props.isCheckBox ? { selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange, getCheckboxProps: getCheckboxProps } : null
"
@change="sortChange"
>
<template #headerCell="scope">
<template v-for="item in renderArr">
<slot v-if="item === scope.column.headerCell" :name="item" :scope="scope" :tableWrapRef="tableWrapRef"></slot>
</template>
<span v-if="!renderArr.includes(scope.column.headerCell)">
{{ scope.column.title }}
</span>
</template>
<template #bodyCell="scope">
<template v-for="item in renderArr">
<slot v-if="item === scope.column.dataIndex" :name="item" :scope="scope" :tableWrapRef="tableWrapRef"></slot>
</template>
<span v-if="!renderArr.includes(scope.column.dataIndex)">
{{ scope.record[scope.column.dataIndex] }}
</span>
</template>
</a-table>
</ConfigProvider>
</div>
<!-- 展示分页 -->
<footer v-if="props.showPagination" class="flex mt-32 mb-12 page-footer">
<span class="mr-10">共{{ props.pagination.total }}条</span>
<a-pagination
v-model:current="props.pagination.current"
v-model:pageSize="props.pagination.pageSize"
:show-quick-jumper="props.showQuickJumper"
showSizeChanger
:total="props.pagination.total"
:page-size-options="props.pageSizeOptions"
@change="onChange"
/>
</footer>
</template>
<script setup>
import imgEmty from '@/assets/images/null-data.png'
import { ref, useSlots, reactive, watch } from 'vue'
import { ConfigProvider } from 'ant-design-vue'
const emits = defineEmits(['pageChange', 'sortChange', 'rowChange'])
const props = defineProps({
dataSource: {
type: Array,
required: true
},
columns: {
type: Array,
required: true
},
rowKey: {
type: String,
default: ''
},
bordered: {
type: Boolean,
default: false
},
showPagination: {
type: Boolean,
default: true
},
showQuickJumper: {
type: Boolean,
default: true
},
pageSizeOptions: {
type: Array,
default: ['10', '20', '30', '40', '50', '500']
},
pagination: {
type: Object,
default: () => {
return {
current: 1,
pageSize: 10,
total: 0
}
}
},
expandIcon: {
type: Function,
default: null
},
loading: {
type: Boolean,
default: false
},
rowClassName: {
type: Function,
default: function () {}
},
customRow: {
type: Function,
default: function () {}
},
isCheckBox: {
type: Boolean,
default: false
},
sticky: {
type: Boolean,
default: true
},
selectedRowKeys: {
type: Array,
default: []
},
getCheckboxProps: {
type: Function,
default: function () {}
}
})
const slots = useSlots()
const tableWrapRef = ref()
const renderArr = Object.keys(slots)
const state = reactive({
selectedRowKeys: []
})
watch(
() => props.selectedRowKeys,
newVal => {
state.selectedRowKeys = [...newVal]
},
{
immediate: true
}
)
const onSelectChange = (selectedRowKeys, selectedRows) => {
state.selectedRowKeys = selectedRowKeys
emits('rowChange', { selectedRowKeys, selectedRows })
}
const onChange = (page, pageSize) => {
emits('pageChange', { pageCurrent: page, pageSize })
state.selectedRowKeys = []
}
const sortChange = (pagination, filters, sorter) => {
emits('sortChange', { pagination, filters, sorter })
}
</script>
<style lang="less" scoped>
.page-footer {
display: flex;
align-items: center;
justify-content: center;
}
.empty {
margin: 50px 0;
}
:deep(.ant-table-striped .ant-table-tbody tr.table-striped td) {
background-color: #f2f3fc;
}
</style>