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"
}
相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端