考虑到分页器的组件内容逻辑比较复杂,所以在创建项目时把el分页器组件(el-pagination)封装成一个简单的组件提高复用性,素材来源于自己工作时的项目,这里尽量将步骤写的详细一些,有需要封装el分页器组件的码友欢迎浏览使用,交流学习。
1. 初始设想与目标
假设你正在开发一个大型Vue应用,其中分页功能在多个地方被频繁使用。为了代码的复用性和可维护性,你决定封装一个自定义的el-pagination
组件,该组件将基于Element Plus的el-pagination
进行扩展,并提供一些自定义功能和属性。
2. 组件结构设计
首先,你需要确定你的PaginationComponent
将需要哪些props和events。例如,你可能需要:
currentPage
(当前页码)pageSize
(每页显示条数)pageSizes
(可选的页面大小数组)total
(总条目数,尽管在这个例子中我们假设它是由外部数据源提供的,不直接作为prop传递)
同时,你还需要定义当页码或页面大小变化时,如何通知父组件。这通常通过自定义事件来完成,如update:currentPage
和update:pageSize
。这里详情可以参考elementUI的官方文档,这里附上国内针对vue3的网址:
3.新建文件
正式做的第一步肯定是新建一个.vue的文件作为组件内容,参考如下图设置:
4.封装代码
参考elementUI官方网站的文档,发现其实并没有给详细的逻辑内容,但是子组件如果想用必须要设置好组件通信等逻辑,同时把样式也写进组件以提高复用性(重点是样式也写进去了)所以这里直接奉上代码(用的是v-model绑定,直接复制即可)
<template>
<!-- 分页 -->
<el-pagination class="custom_page" :currentPage="currentPage" :page-size="pageSize"
:page-sizes="pageSizes" :disabled="disabled" :background="background" :total="total" :pager-count="pagerCount"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
</template>
<script setup>
import { ref, defineEmits } from 'vue';
const currentPage = ref(3);
const pageSize = ref(10);
const pageSizes = [10, 20, 30, 40];
const background = ref(true);
const disabled = ref(false);
const total = ref(100)
const pagerCount = ref(7)
const emit = defineEmits(['update:currentPage', 'update:pageSize']);
const handleSizeChange = (val) => {
console.log(`${val} items per page`)
emit('update:pageSize', val);
}
const handleCurrentChange = (val) => {
console.log(`current page: ${val}`)
emit('update:currentPage', val)
}
</script>
<style>
//这里可以添加子组件的其他样式....
</style>
模板部分主要用于绑定变量,没啥问题直接看api就行(见上)
注意这里的脚本部分:
-
使用
import { ref, defineEmits } from 'vue';
导入了Vue 3的ref
和defineEmits
函数。 -
ref
用于创建响应式的数据,这里创建了currentPage
、pageSize
、background
、disabled
、total
和pagerCount
等变量。 -
defineEmits
用于定义组件可以触发的自定义事件,这里定义了update:currentPage
和update:pageSize
两个事件。 -
handleSizeChange
和handleCurrentChange
是两个方法,分别用于处理页面大小和当前页码的变化。它们会打印出变化的值,并通过emit
函数触发相应的事件,将变化的值传递给父组件。
这里我没有展示style部分,具体内容直接添加标签然后在里面写就行
问题化解
遇到的通信问题:
-
父子组件间数据同步:最初,你可能尝试直接在props中传递
currentPage
和pageSize
,并期望在父组件中直接修改它们(因为我就是这样然后发现分页器最后点不动)。然而,Vue的props是单向数据流,你不能直接在子组件中修改props的值。解决这个问题的方法是使用.sync
修饰符(尽管在Vue 3中推荐使用自定义事件和v-model
的变体),或者更常见的是,在子组件中维护内部状态,并通过事件向父组件发射更新。 -
自定义事件的命名:选择清晰、具有描述性的事件名称对于维护和理解代码至关重要。例如,使用
update:currentPage
和update:pageSize
可以清晰地表明这些事件与当前页码和页面大小的更新有关。 -
避免事件命名冲突:如果你的组件库变得越来越大,确保自定义事件名称的唯一性变得尤为重要。使用命名约定(如前缀)可以帮助避免潜在的命名冲突。还有变量内的命名最好中间不要带横线"-"。
使用组件
组件部分编写好了直接在父组件引用就行,这里由于数值都没有写死,需要在引用的组件中自定义,同样的奉上代码,直接复制粘贴就行,不需要自定义的值可以直接不写,组件会引用其内部的ref中的默认值:
<!-- 父组件引用 -->
<myPagination :total="1000" v-model:currentPage ="currentPage" :pageSizes="[10, 20, 30, 50]" :background="true"layout=" prev, pager, next,sizes,jumper" :pagerCount="8" />
<script setup>
import myPagination from '@components/paginations.vue';
const currentPage = ref(1)//这里如果不在乎警告可以不写,vue会自己识别并更新页面
</script>
<style>
//这里可以添加父组件的其他样式....
</style>
总结
以上就是所以代码,这里直接复制粘贴即可