ant-design-vue中 a-select组件 - 加载大量数据造成卡顿--已解决

解决方案借鉴 列表的滚动加载,实现 a-select 数据展示时滚动加载

隐藏问题:

在ant-design-vue 中 ,select 可以通过 输入文字 匹配 数据源中的数据,但是在滚动加载中,如果暂时还没有加载到该条数据,则不能 匹配 到的这条数据。

具体思路如下:

  1. 监听下拉框展开,下拉框展开后,要重置展示的数据,默认每一次新展开就回到初始加载的数据展示。
  2. 监听数据滚动 - @popupScroll
  3. 滚动条改变后 请求数据加载(可以异步请求,也可以一次性请求后,分批加载)
  4. 对滚动加载 做 防抖处理,限制多次请求(lodash/debounce)
  5. 更新下拉框的数据,需要判断已渲染的下拉长度和当前数据源(总数据)的长度,然后 .concat 拼接数组

但这样会有一个隐藏问题,隐藏问题放在最后再说。根据思路解决 “大量数据加载造成的卡顿” 的问题吧。

前置

  • 引入 ant-design-vue ,注意引入的版本,可参考官方说明
    npm i --save ant-design-vue@next

  • 引入  lodash 
     npm i --save lodash
  • 按需引入 ant-design-vue  中的 Select 组件
    // 引入ant-design-vue 的样式
    import 'ant-design-vue/dist/antd.css';
    // 按需引入 Select 组件
    import { Select } from "ant-design-vue";
    
    const app = createApp(App)
    
    app.use(Select)
    
    app.use(store).use(router).mount("#app");

template

    <!--
      allowClear : 支持清除		false:不清除	
      mode :	设置 Select 的模式为多选或标签	'multiple' | 'tags' | 'combobox'
      show-search 	可输入关键词后,对下拉框数据进行搜索
      popupScroll : 下拉列表滚动时的回调
      change : 选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数
      dropdownVisibleChange : 展开下拉菜单的回调
     -->
    <a-select
      :allowClear="true"
      mode="multiple"
      style="width: 200px"
      placeholder="请选择"
      showArrow
      show-search
      @popupScroll="handlePopupScroll"
      @change="handleChange"
      @dropdownVisibleChange="handleDropdownVisibleChange"
    >
      <a-select-opt-group v-for="item in showList" :key="item">
        <template #label>
          <span> {{ item.letter }} </span>
        </template>
        <a-select-option
          v-for="item in item.letter_arr"
          :key="item"
          :value="item"
          @click="handleClickChange(item)"
          >{{ item }}</a-select-option
        >
      </a-select-opt-group>
    </a-select>

 JS

import { reactive, toRefs } from "vue";
import debounce from "lodash/debounce";
/**
 * 
 * all_Data: 总数据
 * showList:用来展示在 select 下拉框中的数据
 * handlePopupScroll:select 下拉框中的滚动条 滚动时 的回调,做防抖处理
 * handleDropdownVisibleChange:select 下拉框 展开时 的回调监听,open===true,即展开下拉框
 * loadMoreData:滚动条滚动时,showList加载 all_Data 中的数据,更新下拉框的数据
 * handleChange:获取 点击选中的 数据
 * 
*/
export default {
  name: "Home",
  setup() {
    const home_reac = reactive({
      all_Data: [
        {
          letter: "A",
          letter_arr: [
            "a_1",
            "a_2",
            "a_3",
            "a_4",
            "a_5",
            "a_6",
            "a_7",
            "a_8",
            "a_9",
            "a_10",
          ],
        },
        {
          letter: "B",
          letter_arr: [
            "b_1",
            "b_2",
            "b_3",
            "b_4",
            "b_5",
            "b_6",
            "b_7",
            "b_8",
            "b_9",
            "b_10",
          ],
        },
        {
          letter: "C",
          letter_arr: [
            "c_1",
            "c_2",
            "c_3",
            "c_4",
            "c_5",
            "c_6",
            "c_7",
            "c_8",
            "c_9",
            "c_10",
          ],
        },
        {
          letter: "D",
          letter_arr: [
            "d_1",
            "d_2",
            "d_3",
            "d_4",
            "d_5",
            "d_6",
            "d_7",
            "d_8",
            "d_9",
            "d_10",
          ],
        },
        {
          letter: "E",
          letter_arr: [
            "e_1",
            "e_2",
            "e_3",
            "e_4",
            "e_5",
            "e_6",
            "e_7",
            "e_8",
            "e_9",
            "e_10",
          ],
        },
      ],
      showList: [],
    });

    // select - 滚动条 回调 - select数据请求
    const handlePopupScroll = debounce(function () {
      loadMoreData(home_reac.all_Data);
    }, 400);

    // 下拉框打开时 的 回调
    const handleDropdownVisibleChange = (open) => {
      if (open) {
        // 下拉框打开时重置展示的数据
        home_reac.showList = home_reac.all_Data.slice(0, 1);
      }
    };

    // 更新下拉框 展示  的 数据
    const loadMoreData = (dataList) => {
      // 已渲染的下拉列表长度
      const length = home_reac.showList.length;
      // 当前数据源的长度
      const total = dataList.length;
      // 新加载的数据
      let addList = [];
      if (length < total) {
        if (length + 1 <= total) {
          addList = dataList.slice(length, length + 1);
        } else {
          addList = dataList.slice(length, length + (total % 1));
        }
        // 更新下拉框展示的数据
        home_reac.showList = home_reac.showList.concat(addList);
      }
    };

    //数据 筛选
    const handleChange = (item) => {
      console.log("数据筛选", item);
    };

    return {
      ...toRefs(home_reac),
      handlePopupScroll,
      handleChange,
      handleDropdownVisibleChange,
    };
  },
};

这次真是一点也没保留代码,完整的都在这里了~

对了,还有一个隐藏问题,就是:

由于数据是动态加载,当我们第一次请求展示的数据为 “A” 开头的,

此时下拉框中的数据为 A数组 的全部,

那在 input 框中输入关键词搜索时,

将搜索不到 A 以外的其他数据

解决方法暂时有一个方案,但是还没有试验,就是:

当展开下拉框的时候,通过定时器来请求数据,不通过滚动操作来请求加载。

当然,这个方法还没有试验,不确定能不能解决这个问题。 

欢迎关注公众号 “DataShow Charts”呀,我也会在公众号同步发布本篇文章,源码在公众号中~

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值