Skip to content

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('分页查询')
}

最后效果

image.png

Released under the MIT License.