组件库--分页器制作|青训营笔记

80 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天

一、项目简介:

随着前端技术的发展,业界涌现出了许多的UI组件库。例如我们熟知的ElementUI,Vant,AntDesign,IView等等。但是作为一个前端开发者,学会自己制作属于自己的UI组件库已经是很常见的技能了,此次笔记先介绍如何制作一个简易的下拉框组件,以及组件的样式,封装等等

二、组件实现过程:

最终效果:

image.png

实现基础分页主要代码

封装:

image.png

主要传入的值:
  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));
    }
  };

三、总结思考:

这个组件总体让我学到挺多东西的,还有很多剩余空间可以去开发,例如可以改变按钮的样式等等或者其他性能上的优化,例如输入的防抖,动画都是值得去动手的。实现一个分页器真的对小白能学到很多,快去试试