react项目:设计自定义分页输入框

这篇文章针对react项目-Antd组件库-Input组件/InputNumber也适用,改一些属性就可以。

  • 项目需求:是在不确定多少数据的情况下,将所有的数据转换成图片然后下载到本地操作。

在做这个需求的时候我的思路是:

1、Pagination分页组件,先确保点击下一页可以调接口将数据显示,这个里面有个关键点需要注意一下,需要借用到当前组件中的onChange事件,参数为page(页码),pageSize(每页数据大小),要在该事件中修改页数变化,重置分页参数。

  // 每次页码变化重新调用
  const paginationChange = (page: number, pageSize: number) => {
    // 修改页数的变化,重置分页参数
    setFilterParams({
      ...filterParams,
      page,
      pageSize
    });
  };

这个地方的filterParams是useState保存用于向后端接口传入的数据:

  // 分页参数
  const [filterParams, setFilterParams] = useState({
    page: 1,
    size: 10
  });

Pagination组件内容:

 `共 ${total} 条数据 `}
  //page :页码 pageSize:每页大小
  onChange={(page, pageSize) => paginationChange(page, pageSize)}
  //showSizeChanger: 是否展示 pageSize 切换器
  showSizeChanger={false}
/>

2、在上面分页数据可以正常切换页码且可以显示当前页码的数据后,再进行自定义输入框的操作:

在这边我一开始用的是InputNumber组件,因为这样可以省去一些不必要的操作,比如字母、汉字等限制输入,但是这个组件没有输入框中的一键清除的功能,所以在我后面写出来后,还是进行了更换,选择了Input输入框,如果不想做这个效果的话,其实两个都是差不多的。

废话不多说:

Input组件标签内容:

这边因为我也是第一次去做这个东西,有些过于麻烦的思路都想先省去,但是后来还是需要再去修补这些注意事项。就比如在输入框输入的时候,需要注意:

  • 输入框空的情况下,不能以0开头,不然0001这样展示虽然效果没问题,因为我里面用了parseInt,但是如果是作为成品的话是不过关的。
  • 数据是正整数,所以>=0且不能存在小数点
  • 要考虑到复制粘贴过来的情况,这样的话,还是需要限制小数点
  • Input输入框最大取值我尝试了一下是10位数,最大9亿999

这些点还是在完成第一遍的成果之后一次又一次的自测出来的,冒烟测试之前一般都会先自测一遍。

有一点是我后面才发现的,一直以为是功能性BUG:限制小数点的时候,要把中文的“。”也限制住,因为这个中文的“。”在输入框也是能输入的。

我一开始使用的不是onChange事件,而是onPressEnter,按下回车时触发。因为onChange还需要去考虑防抖的问题,技术好的大牛都不屑借助lodash,手动封装一个多有面,对于我一个小菜来说,稍微还是有点费力。我借助了CSDN上其他高手的点,整理了一下(如有侵权冒犯,请立刻联系

手动防抖的方法:


const debounce = (func, wait = 1000) => {

    let timeout; // 定时器变量,用于清除定时器

    return function () {

      clearTimeout(timeout); // 每次触发时先清除上一次的定时器,然后重新计时

      timeout = setTimeout(() => {

      func();

    }, wait); // 指定 多少秒 后触发操作

  };

};

如果是使用lodash的话:

import lodash from 'lodash';

import React, { useCallback } from 'react';

// lodash下的防抖函数

const debounce = lodash.debounce;

// 防抖打印,希望输入的时候,延迟1s后打印值

const data = useCallback(debounce((val:string) => {
    //这里面可以写功能了
    console.log(val);  

}, 1000), []);

需要特别注意的一点:

onChange事件每次输入都会重新创建一个防抖,那么还是会输入多少次创建多少次,虽然只是只执行最后一次的效果,但是对于创建来说还是输入多少次创建了多少次防抖,这个时候需要使用useCallBack就是为了缓存这个函数,避免重复创建。

项目应用操作:

  // input输入框的变化同步到分页数据
  const inputNumberChange = useCallback(
    debounce((e: any) => {
      let num = e.target.value;
      // 转换成数值,以及防止复制过来的数字携带小数点,保留整数部分
      let inputValue = Number(parseInt(num));
      // 防止输入过后在清除掉,空值的情况
      if (isNaN(inputValue)) return;
      // 限制小于等于0的情况
      if (inputValue <= 0) return;
      // 限制最大不能超过999999999
      if (inputValue > 999999999) return;
      setFilterParams({
        ...filterParams,
        size: inputValue,
        page: 1
      });
    }, 1000),
    []
  );
  // onKeyPress时禁止输入小数点及其他特殊数字字符
  const handleKeyPress = (event: any) => {
    const invalidChars = ['-', '+', 'e', '.', '。','E', '-'];
    let value = event.target.value;
    let valueKey = event.key;
    // 阻止无效按键
    if (invalidChars.indexOf(valueKey) !== -1) {
      event.preventDefault();
    }
    // 输入框为空的情况下,不能输入以0开头
    if (value === '' && valueKey === '0') {
      event.preventDefault();
    }
  };

如果不想要在Input组件type为number时,输入框右侧显示上下标进行数字加减,可以使用css技术进行隐藏,我这里是隐藏的。到这一步基本的效果已经呈现出了,记得通过useEffect监听filterParams的变化,每次变化重新获取一下接口数据。

效果图展示:

如有需要指正的地方,请告知,作为小菜虚心接受大佬们的意见!

新手上路,如有侵权,请联系,禁止转载,谢谢!

你可能感兴趣的:(react.js,前端,typescript)