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"
}
相关推荐
老赵的博客7 分钟前
QSS 设置bug
前端·bug·音视频
Chikaoya8 分钟前
项目中用户数据获取遇到bug
前端·typescript·vue·bug
南城夏季8 分钟前
蓝领招聘二期笔记
前端·javascript·笔记
NoloveisGod34 分钟前
Vue的基础使用
前端·javascript·vue.js
GISer_Jing36 分钟前
前端系统设计面试题(二)Javascript\Vue
前端·javascript·vue.js
海上彼尚1 小时前
实现3D热力图
前端·javascript·3d
杨过姑父1 小时前
org.springframework.context.support.ApplicationListenerDetector 详细介绍
java·前端·spring
理想不理想v1 小时前
使用JS实现文件流转换excel?
java·前端·javascript·css·vue.js·spring·面试
惜.己2 小时前
Jmeter中的配置原件(四)
java·前端·功能测试·jmeter·1024程序员节
EasyNTS2 小时前
无插件H5播放器EasyPlayer.js网页web无插件播放器vue和react详细介绍
前端·javascript·vue.js