|
@@ -0,0 +1,215 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <!-- 表格 + 分页 -->
|
|
|
|
|
+ <div class="tablePaganations">
|
|
|
|
|
+ <a-config-provider :locale="locale">
|
|
|
|
|
+ <a-table
|
|
|
|
|
+ class="ant-table-striped"
|
|
|
|
|
+ bordered
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ height="1000px"
|
|
|
|
|
+ :loading="isLoading"
|
|
|
|
|
+ :data-source="dataSource"
|
|
|
|
|
+ :columns="columns"
|
|
|
|
|
+ :row-key="(record) => record.id"
|
|
|
|
|
+ :scroll="scrollValue"
|
|
|
|
|
+ :pagination="havePage ? pagination : false"
|
|
|
|
|
+ :row-class-name="
|
|
|
|
|
+ (_record, index) => (index % 2 === 1 ? 'table-striped' : null)
|
|
|
|
|
+ "
|
|
|
|
|
+ :row-selection="
|
|
|
|
|
+ isSelect
|
|
|
|
|
+ ? {
|
|
|
|
|
+ selectedRowKeys: state.selectedRowKeys,
|
|
|
|
|
+ onSelect: selectEvent,
|
|
|
|
|
+ onSelectAll: selectAllEvent,
|
|
|
|
|
+ }
|
|
|
|
|
+ : null
|
|
|
|
|
+ "
|
|
|
|
|
+ @change="tableChange"
|
|
|
|
|
+ @resize-column="handleResizeColumn"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-for="(item, index) in renderArr"
|
|
|
|
|
+ #[item]="scope"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ >
|
|
|
|
|
+ <slot :name="item" :scope="scope" v-bind="scope || {}" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </a-table>
|
|
|
|
|
+ </a-config-provider>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import {
|
|
|
|
|
+ useSlots,
|
|
|
|
|
+ ref,
|
|
|
|
|
+ reactive,
|
|
|
|
|
+ defineProps,
|
|
|
|
|
+ defineEmits,
|
|
|
|
|
+ defineExpose,
|
|
|
|
|
+ watch,
|
|
|
|
|
+} from 'vue';
|
|
|
|
|
+import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN';
|
|
|
|
|
+const locale = ref(zhCN);
|
|
|
|
|
+const props = defineProps({
|
|
|
|
|
+ dataSource: {
|
|
|
|
|
+ type: Object,
|
|
|
|
|
+ required: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ columns: {
|
|
|
|
|
+ type: Object,
|
|
|
|
|
+ required: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ isSelect: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ },
|
|
|
|
|
+ isLoading: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ },
|
|
|
|
|
+ total: {
|
|
|
|
|
+ type: Number,
|
|
|
|
|
+ default: 0,
|
|
|
|
|
+ },
|
|
|
|
|
+ havePage: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ scrollValue: {
|
|
|
|
|
+ type: Object,
|
|
|
|
|
+ default: () => ({ y: 900 }),
|
|
|
|
|
+ },
|
|
|
|
|
+ selectedKeys: {
|
|
|
|
|
+ type: Array,
|
|
|
|
|
+ default: () => [],
|
|
|
|
|
+ },
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const emit = defineEmits(['getPage', 'getTableSort', 'getSelectColumn']);
|
|
|
|
|
+
|
|
|
|
|
+// 分页配置
|
|
|
|
|
+const pagination = reactive({
|
|
|
|
|
+ showQuickJumper: true,
|
|
|
|
|
+ current: 1,
|
|
|
|
|
+ pageSize: 20, // 默认每页显示数量
|
|
|
|
|
+ showSizeChanger: true, // 显示可改变每页数量
|
|
|
|
|
+ pageSizeOptions: ['10', '20', '50', '100', '200', '500'], // 每页数量选项值
|
|
|
|
|
+ showTotal: (total, range) =>
|
|
|
|
|
+ range[0] + '-' + range[1] + '条' + ' 共' + total + '条', // 显示总数
|
|
|
|
|
+ onShowSizeChange: (current, pageSize) => showSizeChange(current, pageSize),
|
|
|
|
|
+ onChange: (current, pageSize) => changePage(current, pageSize), //点击页码事件
|
|
|
|
|
+ total: props.total,
|
|
|
|
|
+});
|
|
|
|
|
+const lastSorter = reactive({ field: '', order: '' });
|
|
|
|
|
+// 选择数据
|
|
|
|
|
+const state = reactive({
|
|
|
|
|
+ selectedRows: [],
|
|
|
|
|
+ selectedRowKeys: [],
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 改变每页数量时更新显示
|
|
|
|
|
+const showSizeChange = (current, pageSize) => {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ pagination.current = 1;
|
|
|
|
|
+ emit('getPage', pagination.current, pageSize);
|
|
|
|
|
+ });
|
|
|
|
|
+ pagination.pageSize = pageSize;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+//点击页码事件
|
|
|
|
|
+const changePage = (current, size) => {
|
|
|
|
|
+ pagination.current = current;
|
|
|
|
|
+ emit('getPage', pagination.current, size);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 回到第一页
|
|
|
|
|
+const backFirstPage = () => {
|
|
|
|
|
+ pagination.current = 1;
|
|
|
|
|
+ emit('getPage', pagination.current, pagination.pageSize);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 选择每一项操作
|
|
|
|
|
+const selectEvent = (record, selected, selectedRows) => {
|
|
|
|
|
+ state.selectedRows = selectedRows.map(pro => pro);
|
|
|
|
|
+ state.selectedRowKeys = selectedRows.map(pro => pro.id);
|
|
|
|
|
+ emit('getSelectColumn', state);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 点击以后全选当前分页数据
|
|
|
|
|
+const selectAllEvent = (selected, selectedRows, changeRows) => {
|
|
|
|
|
+ if (selected) {
|
|
|
|
|
+ state.selectedRows = selectedRows;
|
|
|
|
|
+ changeRows.forEach(item => {
|
|
|
|
|
+ state.selectedRowKeys.push(item.id);
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ changeRows.forEach(item => {
|
|
|
|
|
+ let index = state.selectedRowKeys.indexOf(item.id);
|
|
|
|
|
+ if (index >= 0) {
|
|
|
|
|
+ state.selectedRows.splice(index, 1);
|
|
|
|
|
+ state.selectedRowKeys.splice(index, 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ emit('getSelectColumn', state);
|
|
|
|
|
+};
|
|
|
|
|
+// 清空选择
|
|
|
|
|
+const clear = () => {
|
|
|
|
|
+ state.selectedRowKeys = [];
|
|
|
|
|
+ state.selectedRows = [];
|
|
|
|
|
+ emit('getSelectColumn', state);
|
|
|
|
|
+};
|
|
|
|
|
+// 获取排序信息
|
|
|
|
|
+const tableChange = (pagination, filters, sorter) => {
|
|
|
|
|
+ // pagination, filters 变化时也会触发所以对sorter进行判断限制执行
|
|
|
|
|
+ if (Object.keys(sorter).length > 0) {
|
|
|
|
|
+ if (sorter.field != lastSorter.field && sorter.order != lastSorter.order) {
|
|
|
|
|
+ lastSorter.field = sorter.field;
|
|
|
|
|
+ lastSorter.order = sorter.order;
|
|
|
|
|
+ emit('getTableSort', sorter);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (sorter.field != lastSorter.field && sorter.order == lastSorter.order) {
|
|
|
|
|
+ lastSorter.field = sorter.field;
|
|
|
|
|
+ lastSorter.order = sorter.order;
|
|
|
|
|
+ emit('getTableSort', sorter);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (sorter.field == lastSorter.field && sorter.order != lastSorter.order) {
|
|
|
|
|
+ lastSorter.field = sorter.field;
|
|
|
|
|
+ lastSorter.order = sorter.order;
|
|
|
|
|
+ emit('getTableSort', sorter);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+// 伸缩列
|
|
|
|
|
+const handleResizeColumn = (w, col) => {
|
|
|
|
|
+ col.width = w;
|
|
|
|
|
+};
|
|
|
|
|
+defineExpose({ backFirstPage, clear });
|
|
|
|
|
+
|
|
|
|
|
+// 监听total变化
|
|
|
|
|
+watch(
|
|
|
|
|
+ props,
|
|
|
|
|
+ newData => {
|
|
|
|
|
+ pagination.total = newData.total;
|
|
|
|
|
+ if (newData.selectedKeys && newData.selectedKeys.length > 0) {
|
|
|
|
|
+ state.selectedRowKeys = newData.selectedKeys;
|
|
|
|
|
+ emit('getSelectColumn', state);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ { immediate: true, deep: true },
|
|
|
|
|
+);
|
|
|
|
|
+// 插槽的实例
|
|
|
|
|
+const slots = useSlots();
|
|
|
|
|
+const renderArr = Object.keys(slots);
|
|
|
|
|
+</script>
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.tablePaganations {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ margin-top: 20px;
|
|
|
|
|
+}
|
|
|
|
|
+.ant-table-striped :deep(.table-striped) td {
|
|
|
|
|
+ background-color: #fafafa;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|
|
|
|
|
+
|
|
|
|
|
+
|