Appearance
分页组件的封装
TIP
这个分页组件只是一个封装,具体实现请自行实现。
CustomPagination.vue
组件
vue
<template>
<div v-if="isPaginationVisible" class="custom-pagination">
<el-pagination
:current-page="innerCurrentPage"
:page-size="innerPageSize"
:total="total"
:layout="layout"
:page-sizes="pageSizes"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
// 定义 props
const props = defineProps({
// 总数据量
total: {
type: Number,
required: true
},
// 每页显示数量
pageSize: {
type: Number,
default: 10
},
// 当前页码
currentPage: {
type: Number,
default: 1
},
// 分页布局
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
// 页大小选项
pageSizes: {
type: Array,
default: () => [10, 20, 30, 50, 100]
},
// 是否显示分页
showPagination: {
type: Boolean,
default: true
},
// 分页大小变化时的回调
onSizeChange: {
type: Function,
default: null
},
// 分页页码变化时的回调
onPageChange: {
type: Function,
default: null
}
});
// 定义 emits
const emit = defineEmits(['update:currentPage', 'update:pageSize']);
// 内部页码状态
const innerCurrentPage = ref(props.currentPage);
// 内部页大小状态
const innerPageSize = ref(props.pageSize);
// 监听外部 currentPage 变化
watch(() => props.currentPage, (newPage) => {
if (newPage !== innerCurrentPage.value) {
innerCurrentPage.value = newPage;
}
});
// 监听外部 pageSize 变化
watch(() => props.pageSize, (newSize) => {
if (newSize !== innerPageSize.value) {
innerPageSize.value = newSize;
// 页大小变化时重置到第一页
innerCurrentPage.value = 1;
}
});
// 处理分页大小变化
const handleSizeChange = (size) => {
innerPageSize.value = size;
innerCurrentPage.value = 1;
emit('update:pageSize', size);
if (props.onSizeChange) {
props.onSizeChange(size);
}
};
// 处理分页页码变化
const handleCurrentChange = (page) => {
innerCurrentPage.value = page;
emit('update:currentPage', page);
if (props.onPageChange) {
props.onPageChange(page);
}
};
// 计算分页是否可见
const isPaginationVisible = computed(() => {
return props.showPagination && props.total > 0;
});
</script>
<style scoped>
.custom-pagination {
margin-top: 15px;
display: flex;
justify-content: flex-end;
}
</style>
<template>
<div v-if="isPaginationVisible" class="custom-pagination">
<el-pagination
:current-page="innerCurrentPage"
:page-size="innerPageSize"
:total="total"
:layout="layout"
:page-sizes="pageSizes"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
// 定义 props
const props = defineProps({
// 总数据量
total: {
type: Number,
required: true
},
// 每页显示数量
pageSize: {
type: Number,
default: 10
},
// 当前页码
currentPage: {
type: Number,
default: 1
},
// 分页布局
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
// 页大小选项
pageSizes: {
type: Array,
default: () => [10, 20, 30, 50, 100]
},
// 是否显示分页
showPagination: {
type: Boolean,
default: true
},
// 分页大小变化时的回调
onSizeChange: {
type: Function,
default: null
},
// 分页页码变化时的回调
onPageChange: {
type: Function,
default: null
}
});
// 定义 emits
const emit = defineEmits(['update:currentPage', 'update:pageSize']);
// 内部页码状态
const innerCurrentPage = ref(props.currentPage);
// 内部页大小状态
const innerPageSize = ref(props.pageSize);
// 监听外部 currentPage 变化
watch(() => props.currentPage, (newPage) => {
if (newPage !== innerCurrentPage.value) {
innerCurrentPage.value = newPage;
}
});
// 监听外部 pageSize 变化
watch(() => props.pageSize, (newSize) => {
if (newSize !== innerPageSize.value) {
innerPageSize.value = newSize;
// 页大小变化时重置到第一页
innerCurrentPage.value = 1;
}
});
// 处理分页大小变化
const handleSizeChange = (size) => {
innerPageSize.value = size;
innerCurrentPage.value = 1;
emit('update:pageSize', size);
if (props.onSizeChange) {
props.onSizeChange(size);
}
};
// 处理分页页码变化
const handleCurrentChange = (page) => {
innerCurrentPage.value = page;
emit('update:currentPage', page);
if (props.onPageChange) {
props.onPageChange(page);
}
};
// 计算分页是否可见
const isPaginationVisible = computed(() => {
return props.showPagination && props.total > 0;
});
</script>
<style scoped>
.custom-pagination {
margin-top: 15px;
display: flex;
justify-content: flex-end;
}
</style>
页面调用
vue
<template>
<div class="table-demo">
<CustomTable
:data="tableData"
:columns="columns"
border
stripe
highlight-current-row
selection
show-index
:operationOptions="operationOptions"
:paginationConfig="paginationConfig"
/>
<CustomPagination
v-model:currentPage="paginationConfig.currentPage"
v-model:pageSize="paginationConfig.pageSize"
:total="tableData.length"
:pageSizes="[5, 10, 15, 20]"
@update:currentPage="fetchData"
@update:pageSize="fetchData"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomTable from '@/components/CustomTable.vue';
import CustomPagination from '@/components/CustomPagination.vue';
const tableData = ref([
// 表格数据...
]);
const columns = ref([
// 表格列配置...
]);
const operationOptions = ref([
// 操作选项...
]);
const paginationConfig = ref({
currentPage: 1,
pageSize: 5
});
// 模拟数据加载
const fetchData = () => {
console.log('加载数据', paginationConfig.value);
// 这里可以添加实际的数据加载逻辑
};
</script>
<template>
<div class="table-demo">
<CustomTable
:data="tableData"
:columns="columns"
border
stripe
highlight-current-row
selection
show-index
:operationOptions="operationOptions"
:paginationConfig="paginationConfig"
/>
<CustomPagination
v-model:currentPage="paginationConfig.currentPage"
v-model:pageSize="paginationConfig.pageSize"
:total="tableData.length"
:pageSizes="[5, 10, 15, 20]"
@update:currentPage="fetchData"
@update:pageSize="fetchData"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomTable from '@/components/CustomTable.vue';
import CustomPagination from '@/components/CustomPagination.vue';
const tableData = ref([
// 表格数据...
]);
const columns = ref([
// 表格列配置...
]);
const operationOptions = ref([
// 操作选项...
]);
const paginationConfig = ref({
currentPage: 1,
pageSize: 5
});
// 模拟数据加载
const fetchData = () => {
console.log('加载数据', paginationConfig.value);
// 这里可以添加实际的数据加载逻辑
};
</script>