antd proFromSelect 懒加载+模糊查询

news/2024/11/15 6:10:48 标签: react.js, javascript, 前端, typescript

antd proFromSelect 懒加载+模糊查询

场景

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

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

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

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

不多说直接上代码

1、标签

<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

  /** 加载动画 */
  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示例

{
    "msg": "成功",
    "data": [
        {
            "label": "666",
            "value": "666"
        },
        {
            "label": "777",
            "value": "777"
        }
    ],
    "code": "00100000"
}

http://www.niftyadmin.cn/n/5752795.html

相关文章

Cuda和Pytorch的兼容性

在安装 PyTorch 时&#xff0c;CUDA 的兼容性通常需要特别注意。CUDA 的兼容性分为两部分&#xff1a;PyTorch 本身的 CUDA 版本和你的系统上安装的 CUDA 驱动版本。 CUDA 驱动的兼容性 1.CUDA 驱动向下兼容&#xff1a;CUDA 驱动程序一般是向下兼容的。这意味着如果你的系统…

Xcode 16 pod init失败的解决方案

目录 前言 一、错误重现 二、解决方案 1.右击项目修改文件展示方式 2.修改.xcodeproj文件 3.参考文档 前言 我们使用Xcode创建新项目之后&#xff0c;执行pod init报错。我们看一下如何解决。 一、错误重现 RuntimeError - PBXGroup attempted to initialize an object …

git-.git目录解析

目录 .git目录下的文件信息 logs&#xff1a;记录各个分支日志记录 refs&#xff1a;记录本地分支、远程分支、tag标签最新commitID config: 配置信息&#xff0c;详细内容解析看下面介绍HEAD: 工作空间当前所在分支 inde文件: 它又常被称为“暂存区”或“缓存区”。这个文件…

算法训练(leetcode)二刷第二十五天 | *134. 加油站、*135. 分发糖果、860. 柠檬水找零、*406. 根据身高重建队列

刷题记录 *134. 加油站*135. 分发糖果860. 柠檬水找零*406. 根据身高重建队列 *134. 加油站 leetcode题目地址 当前站点可以剩余油量gas[i] - cost[i]; 将每站的剩余油量求和计算累计剩余油量&#xff0c;总剩余油量小于0&#xff0c;则无法行驶一周。 若在到达某一站时累计剩…

RabbitMQ-死信队列(golang)

1、概念 死信&#xff08;Dead Letter&#xff09;&#xff0c;字面上可以理解为未被消费者成功消费的信息&#xff0c;正常来说&#xff0c;生产者将消息放入到队列中&#xff0c;消费者从队列获取消息&#xff0c;并进行处理&#xff0c;但是由于某种原因&#xff0c;队列中的…

微信小程序自定义顶部导航栏(适配各种机型)

效果图 1.pages.js&#xff0c;需要自定义导航栏的页面设置"navigationStyle": "custom" 2.App.vue,获取设备高度及胶囊位置 onLaunch: function () {// 系统信息const systemInfo uni.getSystemInfoSync()// 胶囊按钮位置信息const menuButtonInfo uni.…

thinkphp6 --数据库操作 增删改查

一、数据库连接配置 本地测试 直接在.env中修改&#xff0c;不用去config/database.php中修改 正式环境&#xff0c;在部署环境下数据库连接在 config 目录下的 database.php 文件中进行配置&#xff1a; 二、静态方式访问数据库 在tp6 中可以使用 Db 访问数据库&#xff0c;…

云运维基础

笔记内容侵权联系删除 云审计&#xff08;CTS&#xff09; 云审计云上资源变更均可被管控&#xff0c;实时系统性记录所有人的操作&#xff0c;无需手工统计。云审计服务支持将操作记录合并&#xff0c;周期性地生成事件文件实时同步转存到OBS存储桶&#xff0c;帮助用户实现…