antd proFromSelect 懒加载+模糊查询

antd proFromSelect 懒加载+模糊查询

场景

查询用户的时候数量特别大,有10w条数据,不可能直接全部查询用来展示

所以本文章将讲解如何使用懒加载+模糊查询,解决数量过大的问题

后端代码就不用展示了,很简单的分页查询,主要是前端的逻辑

我把返回的json放到最后了,后端就返回这点东西,入参的话就在queryAllUser函数里面,就三个,一个查询的内容,一个页码一个当页数量

不多说直接上代码

1、标签

react 复制代码
<ProFormSelect
            rules={[
              {
                required: true,
                message: `名字为必填项`,
              },
            ]}
            placeholder="请选择"
            name="id"
            label="名字"
            width={`md`}
            fieldProps={{
        // 可搜索
              showSearch: true,
                  // 多选下通过响应式布局让选项自动收缩
              maxTagCount: 'responsive',
                  // 设置 false 时关闭虚拟滚动
              virtual: true,
                  // 下拉列表滚动时的回调
              onPopupScroll: e => handleScroll(e),
                  // 文本框值变化时回调
              onSearch: handleSearchChange,
              // 这里可加入自定义加载动画
              dropdownRender: menu => (
                <>
                  {menu}
                  {loading && (
                    <div
                      style={{
                        width: '100%',
                        height: '50px',
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                      }}
                    >
                      <Spin />
                    </div>
                  )}
                </>
              )
            }}
    // 数据
            options={dataSource}
          />

2、JS

react 复制代码
  /** 加载动画 */
  const [loading, setLoading] = useState(false);
  /** 数据 */
  const [dataSource, setDataSource] = useState<any>([]);
  /** 查询改变的值 */
  const [searchChangeValue, setSearchChangeValue] = useState<string>('');
  /** 页码 */
  const [currentPage, setCurrentPage] = useState<number>(1);

  // 下一页
  const getNextPage = async () => {
    // 等于 -1 就是没值了 不需要再加载了
    if (currentPage === -1) {
      return;
    }
    try {
      // 查询
      const { code, msg, data } = await queryAllUser({
        name: searchChangeValue,
        currentPage,
        pageSize: 10,
      });
        // code 不等于 001 时 为查询失败
      if (code !== "001") {
        message.error(msg)
        return
      }
        // 开启加载动画
      setLoading(true);
      const newData: any = data;
        // 第一页的时候 不需要之前的数据(原始数据)
      if (currentPage === 1) {
        setDataSource([...newData])
      } else {
          // 不是第一页的时候 把查出来的数据放到原始数据(之前的数据)后
        setDataSource((prevData: any) => [...prevData, ...newData]);
      }
       	// 页面 +1
      setCurrentPage(pre => (pre += 1));
        // 不等于 10个 的时候说明查完了
        // 就算刚好最后剩 10个 再走一遍逻辑就好了
      if (newData.length !== 10) {
          // 关闭加载动画、鼠标滚动时不加载
        setCurrentPage(-1);
        setLoading(false);
      }
    } catch (error) {
      console.log(error);
    } finally {
      setLoading(false);
    }
  };

  // 监听滚动条
  const handleScroll = (event: any) => {
    const { scrollTop, offsetHeight, scrollHeight } = event.target;
    if (scrollTop + offsetHeight === scrollHeight) {
          // 鼠标滚动时不加载
      if (currentPage !== -1) {
        getNextPage();
      }
    }
  };

  // 防抖函数(搜索时使用)
  const debounce = (func: { (value: any): void; apply?: any }, delay: number | undefined) => {
    let timerId: string | number | NodeJS.Timeout | undefined;
    return (...args: any) => {
      clearTimeout(timerId);
      timerId = setTimeout(() => {
        // eslint-disable-next-line prefer-spread
        func.apply(null, args);
      }, delay);
    };
  };

  // 搜索
  const handleSearchChange = debounce((value: any) => {
      // 给查询条件赋值
    setSearchChangeValue(value)
    const fn = async () => {
      try {
        // 搜索的时候已经查了第一页了 懒加载从第二页开始查
        setCurrentPage(2)
        const { code, msg, data } = await queryAllUser({
          name: value,
          currentPage: 1,
          pageSize: 10,
        });
        if (code !== "001") {
          message.error(msg)
          return
        }
        const newData = data;
          // 由于查询时从第一页开始就不需要原始数据了
        setDataSource([...newData]);
      } catch (error) {
        console.log(error);
      }
    };
    fn();
  }, 1000);

// 页面初始化加载
  useEffect(() => {
    getNextPage();
  }, []);

3、json示例

json 复制代码
{
    "msg": "成功",
    "data": [
        {
            "label": "666",
            "value": "666"
        },
        {
            "label": "777",
            "value": "777"
        }
    ],
    "code": "00100000"
}
相关推荐
Python私教6 分钟前
如意Agent日志系统重构:从 print() 大海捞针到结构化可观测性栈
java·前端·重构
拉里呱唧18 分钟前
一个像在使用PPT的在线 HTML 编辑器:HeyHTML
javascript·交互·html5
We་ct24 分钟前
LeetCode 97. 交错字符串:动态规划详解
前端·算法·leetcode·typescript·动态规划
Chengbei1133 分钟前
轻量化 Web 安全日志分析神器 星川智盾日志威胁检测、地理溯源、MITRE ATT&CK 映射,支持 Windows/macOS/Linux
前端·人工智能·安全·web安全·macos·系统安全·安全架构
风流 少年35 分钟前
Python Web框架:FastAPI
前端·python·fastapi
GISer_Jing43 分钟前
AI时代面试新常态——从“会用工具”到“深挖原理”的跨越
前端·人工智能·ai编程
IT_陈寒1 小时前
React的useEffect把我坑惨了,这些闭包陷阱真要命
前端·人工智能·后端
前端之虎陈随易1 小时前
有生之年系列,Nodejs进程管理pm2 v7.0发布
前端·typescript·npm·node.js
ayqy贾杰1 小时前
Cursor SDK发布!开发者可直接搬走其内核
前端·vue.js·面试