这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
一、项目简介:
随着前端技术的发展,业界涌现出了许多的UI组件库。例如我们熟知的ElementUI,Vant,AntDesign,IView等等。但是作为一个前端开发者,学会自己制作属于自己的UI组件库已经是很常见的技能了,此次笔记先介绍如何制作一个简易的下拉框组件,以及组件的样式,封装等等
二、组件实现过程:
最终效果:
实现基础分页主要代码
封装:
主要传入的值:
queryPageProps: {
// 当前页数
currentPage: {
type: Number,
default: 1,
},
// 总条目数
total: {
type: Number,
default: 100,
required: true,
},
// 每页显示的条目个数
pageSize: {
type: Number,
default: 5,
required: true,
},
// 页码按钮数量
pageCount: {
type: Number,
default: 5,
required: true,
},
}
事件
queryPageEmit: ['change-page'],
实现的难点之一:判断插入...
由于我们的按钮数量是有限的,所以我们要判断当前的页数的同时在合适的位置插入...代表中间的按钮数量省略显示,并且在点击...时可以往后翻页
例如实现在中间页时怎么插入...
// 当前页处于中间页的位置
const firstList = [];
firstList.push(1);
firstList.push('...');
const justCenter = Math.ceil((props.pageCount - 2) / 2);
for (let i = 1; i <= props.pageCount - 2; i++) {
if (i < justCenter) {
firstList.push(props.currentPage - (justCenter - i));
} else if (i == justCenter) {
firstList.push(props.currentPage);
} else {
firstList.push(props.currentPage + (i - justCenter));
}
}
firstList.push('...');
firstList.push(pageTotal.value);
return firstList;
其他的不再展示,代码有点多
主要实现思路就是判断当前页是处于靠前还是中间还是靠后,靠前就在前面显示,靠后就在后面显示,中间就是两边都要显示,通过生产数组,判断位置将合适的元素push进去。
方法:
// 上一页
const prevEvent = () => {
/* 函数名要对应,要完全相同,'-'和驼峰不能相等 */
if (props.currentPage > 1) {
emit('change-page', props.currentPage - 1);
}
};
// 下一页
const nextEvent = () => {
if (props.currentPage < pageTotal.value) {
emit('change-page', props.currentPage + 1);
}
};
// 点击某一页
const itemEvent = (item: any, index: number) => {
// 按钮的中间数
let center = Math.ceil((props.pageCount + 1) / 2);
if (item !== '...' && item !== props.currentPage) {
emit('change-page', item);
} else if (item === '...') {
if (index + 1 <= center) {
if (props.currentPage <= 5) {
emit('change-page', 1);
} else {
emit('change-page', props.currentPage - 5);
}
} else {
if (pageTotal.value - props.currentPage <= 5) {
emit('change-page', pageTotal.value);
} else {
emit('change-page', props.currentPage + 5);
}
}
}
};
当点击...时我们可以判断向前或向后移动想要的距离,这里我不再封装,固定移动5页
实现一页的大小变化:
这边我直接用了select组件,可以从上篇文章看如何实现
要做的就是监听页面大小的变化
watch(
() => props.pageSize,
(newValue, oldValue) => {
pageTotal.value = Math.ceil(props.total / newValue);
},
);
其他没有什么难点
实现输入目标页数跳转
<!-- 跳转至第几页 -->
<div
class="to-page"
}"
v-show="props.jumperShow == true"
>
<span>前往</span>
<input
type="text"
@blur="handleAddNumber(toNumber)"
v-model="toNumber"
@keyup.enter.native="handleAddNumber(toNumber)"
/>
<span>页</span>
</div>
我们通过@blur和@keyup.enter.native属性来获取输入框的值进行emit传值,要注意的一点就是输入比总页数更大值的时候记得做个判断。
// 到第几页
const toNumber = 1;
const handleAddNumber = (toNumber: number) => {
// 总的页数
if (toNumber <= 0) {
toNumber = 1;
emit('change-page', 1);
} else if (toNumber > pageTotal.value) {
toNumber = pageTotal.value;
emit('change-page', pageTotal.value);
} else {
emit('change-page', Number(toNumber));
}
};
三、总结思考:
这个组件总体让我学到挺多东西的,还有很多剩余空间可以去开发,例如可以改变按钮的样式等等或者其他性能上的优化,例如输入的防抖,动画都是值得去动手的。实现一个分页器真的对小白能学到很多,快去试试