目录
- 前言
- 1. 基本知识
- 2. Demo
- 3. 实战
前言
需求:从无到有做一个分页并且附带分页的导入导出增删改查等功能
前提一定是要先有分页,作为全栈玩家,先在前端部署一个分页的列表
相关后续的功能,是Java,推荐阅读:
- java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
- 【Java项目】实战CRUD的功能整理(持续更新)
1. 基本知识
主要是用于在数据量较大的情况下,将数据分成多个页面显示
通过分页,可以避免一次性加载大量数据导致的性能问题,并且可以使用户更方便地浏览数据
怎样才能做到这样一个页面,需要先了解一些基本的知识,可以提前去官网预热下:官网补充说明
需要注意的点(每一步都比较重要,不然会丢失数据,查询不到)
- 绑定值:
current-page
和page-size
需要与组件中的数据绑定,以确保分页状态和显示的一致性 - 事件处理:需要处理分页组件的
current-change
和size-change
事件,以便在用户改变当前页或每页条目数时更新数据 - 数据同步:分页状态变化时,需要确保组件显示的数据和分页控件保持同步
对应的属性说明:
current-page
:当前页数,类型为 Numberpage-size
: 每页显示条目个数,类型为 Numbertotal
:总条目数,类型为 Numberpage-sizes
:显示个数的选择器,类型为 Arraylayout
:组件布局,子组件名用逗号分隔
常用的子组件有 prev, pager, next, jumper, total, sizes, ->, slotsmall
: 小型分页样式,类型为 Boolean,默认为false
相关的事件设置有如下:
current-change
:当前页变化时触发,返回当前页数。size-change
:每页条目数变化时触发,返回新的每页条目数
2. Demo
基本的Demo主要以形式展示为主
示例 1:基本使用
<template>
<el-pagination
:total="100"
:page-size="10"
v-model:current-page="currentPage"
layout="prev, pager, next"
@current-change="handlePageChange"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const currentPage = ref(1)
const handlePageChange = (page: number) => {
console.log(`Current page changed to: ${page}`)
}
</script>
示例 2:带有每页条目数选择器
<template>
<el-pagination
:total="1000"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 30, 50]"
layout="sizes, prev, pager, next"
@size-change="handleSizeChange"
@current-change="handlePageChange"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const currentPage = ref(1)
const pageSize = ref(10)
const handlePageChange = (page: number) => {
console.log(`Current page changed to: ${page}`)
}
const handleSizeChange = (size: number) => {
console.log(`Page size changed to: ${size}`)
}
</script>
示例 3:显示总条目数和跳转页码
<template>
<el-pagination
:total="500"
v-model:current-page="currentPage"
layout="total, prev, pager, next, jumper"
@current-change="handlePageChange"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const currentPage = ref(1)
const handlePageChange = (page: number) => {
console.log(`Current page changed to: ${page}`)
}
</script>
示例 4:使用小型分页样式
<template>
<el-pagination
:total="200"
v-model:current-page="currentPage"
layout="prev, pager, next"
:small="true"
@current-change="handlePageChange"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const currentPage = ref(1)
const handlePageChange = (page: number) => {
console.log(`Current page changed to: ${page}`)
}
</script>
示例 5:响应式分页按钮数量
<template>
<el-pagination
:total="300"
v-model:current-page="currentPage"
:pager-count="pagerCount"
layout="prev, pager, next"
@current-change="handlePageChange"
/>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue'
const currentPage = ref(1)
const pagerCount = computed(() => document.body.clientWidth < 768 ? 5 : 7)
const handlePageChange = (page: number) => {
console.log(`Current page changed to: ${page}`)
}
</script>
3. 实战
可以定义新的一套模版
<template>
<el-pagination
:background="true"
:page-sizes="[5, 10, 30, 50]"
:pager-count="pagerCount"
:total="total"
v-show="total > 0"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
class="float-right mb-15px mt-15px"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</template>
<script lang="ts" setup>
import { computed, watchEffect, ref } from 'vue'
defineOptions({ name: 'Pagination' })
// 定义组件接收的 props
const props = defineProps({
// 总条目数
total: {
required: true,
type: Number
},
// 当前页数,默认为 1
page: {
type: Number,
default: 1
},
// 每页显示条目个数,默认为 20
limit: {
type: Number,
default: 20
},
// 最大页码按钮数,移动端默认值为 5,桌面端为 7
pagerCount: {
type: Number,
default: document.body.clientWidth < 992 ? 5 : 7
}
})
// 定义组件发出的事件
const emit = defineEmits(['update:page', 'update:limit', 'pagination'])
// 计算属性,用于双向绑定 currentPage 和 pageSize
const currentPage = computed({
get() {return props.page},
set(val) {emit('update:page', val)}
})
const pageSize = computed({
get() {return props.limit},
set(val) {emit('update:limit', val)}
})
// 处理每页条目数变化的函数
const handleSizeChange = (val) => {
// 如果修改后当前页超过最大页面,则跳转到第一页
if (currentPage.value * val > props.total) {
currentPage.value = 1
}
emit('pagination', { page: currentPage.value, limit: val })
}
// 处理当前页变化的函数
const handleCurrentChange = (val) => {
emit('pagination', { page: val, limit: pageSize.value })
}
</script>
<style>
/* 可选样式 */
.float-right {
float: right;
}
.mb-15px {
margin-bottom: 15px;
}
.mt-15px {
margin-top: 15px;
}
</style>
之后通过这个模版 直接引用(实战提取的Demo)
<template>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</template>
<script setup lang="ts">
import { GoodsStoragePlanApi } from '@/api/dangerous/goodsstorageplan'
import { ref, reactive, onMounted } from 'vue'
const loading = ref(true)
const list = ref([])
const total = ref(0)
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
createTime: [],
})
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await GoodsStoragePlanApi.getGoodsStoragePlanPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>