需求

  • ant-design-vue select下拉列表当中动态加载列表,当滚动到最后的时候继续加载,没有数据了就不加载了
  • 这里的defHttp就是axios的二次封装,你们可以替换为axios就可以
  • 效果的话就不展示了,因为数据都是后台请求的~

做法

  • 用到的ant design vue组件有
    • a-spin加载圈圈的
    • a-select下拉列表
    • a-empty空状态的(这里自定义了空状态,使其文字替换为加载圈圈)

示例

//必须要写
const VNodes =  (_, { attrs }) => {
    return attrs.vnodes;
}
<a-select
          v-model:value="searchForm.userIds"
          allow-clear
          mode="multiple"
          @dropdownVisibleChange="handleDropDownVisibleChange"
          @popupScroll="handlePopupScroll"
          :max-tag-count="1"
          :max-tag-text-length="2"
          placeholder="请选择">
          <a-select-option v-for="item in dropDownData.options" :key="item.id" :value="item.id">
            {{item.name}}
          </a-select-option>
          
          <template #dropdownRender="{ menuNode: menu }">
            <a-empty v-if="dropDownData.isLoading">
              <template #description>
                <span><a-spin /></span>
              </template>
            </a-empty>
            <a-empty v-else-if="dropDownData.options.length === 0">
              <template #description>
                暂无数据
              </template>
            </a-empty>
            <!--显示结果-->
			<!--v-nodes必须要写在最后面,这个代表要渲染的下拉列表数据-->
            <template v-else>
              <v-nodes :vnodes="menu" />
            </template>
           </template>
        </a-select>


//要发送给后台的数据
const searchForm = ref<SearchFormTypes>({
  userName:'',
  userIds:[],//记录用户选取的下拉列表数据
});

/* 下拉列表请求-初次的时候 */
const handleDropDownVisibleChange = async (open) => {
  if(open && dropDownData.value.options.length === 0 ){
    //初次加载
    const result = await defHttp.post(({url:'/xxxx',params:{userName:searchForm.value.userName,...dropDownData.value.pagination}}));
    dropDownData.value.pagination.total = result.total ?? 0;
    dropDownData.value.isLoading = false;
    //从结果中map获取列表数据
    dropDownData.value.options = result?.list?.map(item => ({
      id:item.id ?? 0,
      name:item.name ?? "",
    })) ?? [];
  }
}

/* 下拉滚动 */
const handlePopupScroll = async (e) => {
	//已经有的下拉项目 大于等于后台返回的下拉项总长度,那么就返回不请求了
  if(dropDownData.value.options.length >= dropDownData.value.pagination.total) return;
  const { scrollHeight, scrollTop, clientHeight } = e.target;
  if (scrollHeight - scrollTop === clientHeight) {
	//到达了底部,请求数据
    dropDownData.value.pagination.page++;//分页器自增1
    const result = await defHttp.post(({url:'/xxxxx',params:{userName:searchForm.value.userName,...dropDownData.value.pagination}}));
    //从结果中map获取列表数据
    const temp = result?.list?.map(item => ({
      id:item.id ?? 0,
      name:item.name ?? "",
    })) ?? [];
    //注意顺序,这里是先结构之前的,在结构之后的
    dropDownData.value.options = [...dropDownData.value.options,...temp];
  }
}

// 下拉列表
const dropDownData = ref<dropDownDataTypes>({
  options:[],//下拉项列表
  pagination:{
    page:1,
    pageSize:10,
    total:0,//用于记录数据总长度,后期判断是否还继续加载
  },//分页器下拉的
  isLoading:true, //是否正在加载数据
})

回调说明和其他的一些说明

  • @dropdownVisibleChange="handleDropDownVisibleChange"初次选择下拉列表的时候执行,可以用于初始化数据
  • @popupScroll="handlePopupScroll"下拉列表滚动的时候执行的回调,用于判断是否加载到了底部
  • <v-nodes :vnodes="menu" />这个代表的就是那个下拉列表项数据,没有这个就不渲染

参考文章

https://blog.csdn.net/qq_36437172/article/details/109515201

Logo

前往低代码交流专区

更多推荐