Appearance
Pagination分页组件
接下来我们简单实现一个分页组件的封装,同样也是先实现功能,然后再进行封装和不断迭代优化
1、组件搭建和注册
☞ 这里我们同样是使用element-plus的组件,先搭建一个分页组件的文件,然后进行布局
☞ src/components/Pagination/index.vue
JS
<el-pagination background
layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[12, 20, 50, 100]" :total="1000" />
☞ main.ts根目录引入注册
JS
import Pagination from '@/components/Pagination/index.vue' //分页组件
app.component('Pagination', Pagination) //分页组件
☞ 页面之中使用
JS
<Pagination />
2、分页功能实现
简单布局以后,我们就可以看到分页组件的基本功能已经实现了,但是这里我们还需要实现一些功能,比如:
JS
- 分页切换
- 每页显示条数切换
- 跳转到指定页
- 输入页码回车跳转
这里我们实现一下分页的功能
JS
<template>
<div class="components-pagination">
<el-pagination
layout="total, sizes, prev, pager, next, jumper,->"
:page-sizes="[12, 20, 50, 100]"
:total="400" :size="size"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:disabled="disabled"
:background="background"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"/>
</div>
</template>
<script setup>
import { computed, defineProps, ref } from "vue"
const currentPage = ref(1)
const pageSize = ref(10)
const disabled = ref(false)
const background = ref(true)
const size = ref('default')
const handleSizeChange = (val) => {
console.log(`${val} items per page`)
}
const handleCurrentChange = (val) => {
console.log(`current page: ${val}`)
}
</script>
<style scoped>
.components-pagination {
width: 100%;
display: flex;
justify-content: right;
}
</style>
3、功能封装
解下来我们就把方法和对应的部分暴露在我们的组件中,就封装好了
JS
<template>
<div class="components-pagination">
<el-pagination :layout="layout"
:page-sizes="pageSizes"
:total="total"
:size="size"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:disabled="disabled"
:background="background"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:pager-count="5">
</el-pagination>
</div>
</template>
<script setup>
import { computed, defineProps, ref, watch, defineEmits } from "vue"
// 定义组件的 props,支持传入各种配置项
const props = defineProps({
currentPage: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 10
},
total: {
type: Number,
required: true
},
size: {
type: String,
default: 'default'
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper, ->'
},
pageSizes: {
type: Array,
default: () => [10, 20, 30, 100]
},
disabled: {
type: Boolean,
default: false
},
background: {
type: Boolean,
default: true
}
})
// 通过 `defineEmits` 声明事件
const emit = defineEmits(['update:currentPage', 'update:pageSize','pagination'])
// 计算属性和响应式数据
// const currentPage = ref(props.currentPage)
// const pageSize = ref(props.pageSize)
const currentPage = computed({
get() {
return props.currentPage
},
set(val) {
emit('update:currentPage', val)
}
})
const pageSize = computed({
get() {
return props.pageSize
},
set(val){
emit('update:pageSize', val)
}
})
const size = ref(props.size)
const disabled = ref(props.disabled)
const background = ref(props.background)
const pageSizes = ref(props.pageSizes)
const layout = ref(props.layout)
const total = ref(props.total)
// 响应式处理分页参数
watch(() => props.currentPage, (newVal) => {
currentPage.value = newVal
})
watch(() => props.pageSize, (newVal) => {
pageSize.value = newVal
})
watch(() => props.disabled, (newVal) => {
disabled.value = newVal
})
watch(() => props.background, (newVal) => {
background.value = newVal
})
watch(() => props.pageSizes, (newVal) => {
pageSizes.value = newVal
})
watch(() => props.layout, (newVal) => {
layout.value = newVal
})
watch(() => props.total, (newVal) => {
total.value = newVal
})
// 处理每页显示项数变化
const handleSizeChange = (val) => {
// console.log(`${val} items per page`)
// 如果需要传递这个值到父组件,可以通过 emit
// emit('update:pageSize', { currentPage: currentPage.value, pageSize: val });
emit('pagination', { currentPage: currentPage.value, pageSize: val });
}
// 处理当前页变化
const handleCurrentChange = (val) => {
// console.log(`current page: ${val}`)
// 如果需要传递这个值到父组件,可以通过 emit
// emit('update:currentPage',{ currentPage: val, pageSize: pageSize.value });
emit('pagination',{ currentPage: val, pageSize: pageSize.value })
}
</script>
<style scoped>
.components-pagination {
width: 100%;
display: flex;
justify-content: flex-end;
padding: 20px 10px;
}
.components-pagination .el-select {
min-width: 80px;
}
.el-pagination .el-select {
width: 80px;
}
</style>
4、父组件使用
这里我们传入一个总页数,然后绑定当前页和每页显示条数,就可以实现分页的功能了
js
<Pagination v-show="totalvalue > 0"
:total="totalvalue"
v-model:current-page="queryParams.pageNum"
v-model:page-size="queryParams.pageSize"
@pagination="getList"/>
const getList=()=> {
console.log('分页查询')
}
最后效果