| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- <template>
- <div class="tablePaganations">
- <!-- <a-config-provider :locale="locale"> -->
- <a-table
- id="commonTable" class="ant-table-striped" bordered size="small" height="1000px" :loading="isLoading"
- :data-source="dataSource" :columns="columns" :row-key="(record) => record.id" :scroll="{ y: yScroll }"
- :pagination="havePage ? pagination : false" :row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)
- " :row-selection="isSelect
- ? {
- type: selectType === 'radio' ? 'radio' : 'checkbox',
- selectedRowKeys: state.selectedRowKeys,
- onSelect: selectEvent,
- onSelectAll: selectAllEvent,
- hideSelectAll: hideSelectAll,
- }
- : null
- " :custom-row="isCustomRowClick ? customRowClick : 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,
- onMounted,
- } from 'vue';
- import { getTableScroll } from '../common/tableScroll.js';
- // 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,
- },
- // 表格loading
- isLoading: {
- type: Boolean,
- },
- // 数据总数
- total: {
- type: Number,
- default: 0,
- },
- // 是否分页
- havePage: {
- type: Boolean,
- default: true,
- },
- // 是否隐藏全选
- hideSelectAll: {
- type: Boolean,
- default: false,
- },
- // 单选多选
- selectType: {
- type: String,
- default: 'checkbox',
- },
- // 分页在右上角
- topRight: {
- type: Boolean,
- default: false,
- },
- // 表格距底部高度
- extraHeight: {
- type: Number,
- default: undefined,
- },
- // 选择的key值
- selectedKeys: {
- type: Array,
- default: () => [],
- },
- // 是否自定义行点击
- isCustomRowClick: {
- type: Boolean,
- default: false,
- },
- // 自定义默认数量
- defaultPageSize: {
- type: Number,
- default: 20,
- },
- });
- const emit = defineEmits(['getPager', 'getSorter', 'getSelected', 'customRowClick']);
- // 分页配置
- const pagination = reactive({
- showQuickJumper: true,
- current: 1,
- pageSize: props.defaultPageSize, // 默认每页显示数量
- 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,
- position: props.topRight ? ['topRight'] : ['bottomRight'],
- });
- const yScroll = ref(400); //默认滚动高度
- const extraHeight = ref(undefined); //表格距离底部值
- // 最后一次排序信息
- const lastSorter = reactive({ field: '', order: '' });
- // 选择的数据
- const state = reactive({
- selectedRows: [],
- selectedRowKeys: [],
- });
- onMounted(() => {
- if (!props.havePage) {
- extraHeight.value = 30;
- } else {
- extraHeight.value = props.extraHeight;
- }
- if (props.extraHeight) {
- extraHeight.value = props.extraHeight;
- }
- onResizeTable();
- window.onresize = () => {
- onResizeTable();
- };
- });
- // 表格位置
- const onResizeTable = () => {
- yScroll.value = getTableScroll({
- extraHeight: extraHeight.value,
- id: 'commonTable',
- });
- };
- //点击页码事件
- const changePage = (current, size) => {
- pagination.current = current;
- emit('getPager', pagination.current, size);
- };
- // 改变每页数量时更新显示
- const showSizeChange = (current, pageSize) => {
- setTimeout(() => {
- pagination.current = 1;
- emit('getPager', pagination.current, pageSize);
- });
- pagination.pageSize = pageSize;
- };
- // 回到第一页
- const backFirstPage = () => {
- pagination.current = 1;
- emit('getPager', pagination.current, pagination.pageSize);
- };
- // 伸缩列
- const handleResizeColumn = (w, col) => {
- col.width = w;
- };
- // 选择每一项操作
- const selectEvent = (record, selected) => {
- if (props.selectType === 'radio') {
- state.selectedRows = [record];
- state.selectedRowKeys = [record.id];
- } else {
- if (selected) {
- state.selectedRows.push(record);
- state.selectedRowKeys.push(record.id);
- } else {
- let index = state.selectedRowKeys.indexOf(record.id);
- if (index >= 0) {
- state.selectedRows.splice(index, 1);
- state.selectedRowKeys.splice(index, 1);
- }
- }
- }
- emit('getSelected', state);
- };
- // 点击以后全选当前分页数据
- const selectAllEvent = (selected, selectedRows, changeRows) => {
- if (selected) {
- changeRows.forEach(item => {
- state.selectedRows.push(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('getSelected', state);
- };
- // 清空选择
- const clear = () => {
- state.selectedRowKeys = [];
- state.selectedRows = [];
- emit('getSelected', 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('getSorter', sorter);
- }
- if (sorter.field != lastSorter.field && sorter.order == lastSorter.order) {
- lastSorter.field = sorter.field;
- lastSorter.order = sorter.order;
- emit('getSorter', sorter);
- }
- if (sorter.field == lastSorter.field && sorter.order != lastSorter.order) {
- lastSorter.field = sorter.field;
- lastSorter.order = sorter.order;
- emit('getSorter', sorter);
- }
- }
- };
- // 自定义行点击
- const customRowClick = record => {
- return {
- onDblclick() {
- emit('customRowClick', record);
- },
- };
- };
- // 暴露出方法
- defineExpose({ backFirstPage, clear });
- // 监听total变化
- watch(
- props,
- newData => {
- pagination.total = newData.total;
- extraHeight.value = newData.extraHeight;
- },
- { immediate: true, deep: true },
- );
- watch(
- () => props.selectedKeys,
- newData => {
- state.selectedRowKeys = newData;
- state.selectedRows = newData.map(item => props.dataSource.find(data => data.id === item));
- emit('getSelected', state);
- console.log(state.selectedRows);
- },
- { immediate: true, deep: true },
- );
- // 插槽的实例
- const slots = useSlots();
- const renderArr = Object.keys(slots);
- </script>
- <style scoped>
- .tablePaganations {
- width: 100%;
- /* margin-top: 8px; */
- }
- .ant-table-striped :deep(.table-striped) td {
- background-color: #fafafa;
- }
- </style>
|