select组件 消费 含糊查找/分页接口 编码实践

需求场景

有些后端接口是分页并支持含糊查找的,咱们需要编写代码用select组件去展现列表数据,而且支持查找才能(用select组件消费这个接口)

源码

html:

<某某组件库-select
 v-model="formParams.model.sceneModelList"
 placeholder="请挑选界面"
 :filterable="true"
 :remote="true"
 :debounce="500"
 multiple
 :remote-method="getSceneModelListByKeyword"
 :loading="isGettingSceneModelList"
 value-key="id"
 :formatter="formatterDataModel"
 @blur="onBlur"
 @scroll-bottom="selectScrollBottom"
>
 <某某组件库-option
  v-for="item in sceneModelList"
  :key="item.id"
  :label="item.name"
  :value="item"
 />
 <某某组件库-loading v-if="isScrollLoading" size="small" />
</某某组件库-select>

js:

// 数据模型select分页相关
// 数据模型select翻滚触底时触发分页接口拜访
const isGettingSceneModelList = ref(true);
const sceneModelList = ref<TDataModelList>([]);
const isScrollLoading = ref(false);
const noMoreData = ref(false);
let page = 1;
const size = 20;
let keyword = '';
// 翻滚触底回调
const selectScrollBottom = async () => {
 if (noMoreData.value) return;
 isScrollLoading.value = true;
 page += 1;
 const params = {
  page,
  size,
  keyword,
  };
 const [error, res] = await to(getSceneModelList(params));
 if (error) {
  return Message({ message: error.message, type: 'error' });
  }
 if (res.data.items === null || res.data.items.length === 0) {
  isScrollLoading.value = false;
  noMoreData.value = true;
  return;
  }
 sceneModelList.value = [...sceneModelList.value, ...(res.data.items || [])];
 isScrollLoading.value = false;
};
// 长途查找回调
const getSceneModelListByKeyword = async (input = '') => {
 page = 1;
 keyword = input;
 isGettingSceneModelList.value = true;
 const params = {
  page,
  size,
  keyword,
  };
 const [error, res] = await to(getSceneModelList(params));
 if (error) {
  return Message({ message: error.message, type: 'error' });
  }
 sceneModelList.value = res.data.items || [];
 isGettingSceneModelList.value = false;
};
getSceneModelListByKeyword();
// 失掉焦点时清空查找要害
const onBlur = () => {
 keyword = '';
};
// 数据模型格式化
const formatterDataModel = ({ value }: { value: IDataModelItem }) => {
 return value?.name;
};

实现select适配分页

比方咱们假定一页的size为20,咱们的目标便是最初select恳求第一页(page = 1)的20条数据,后边每次翻滚触底时再恳求第二页、第三页…的数据,直至后端数据悉数被恳求完毕,也便是page过大导致回来数据为空时,咱们不再触发恳求的逻辑。

咱们暂时不考虑查找才能的实现,所以暂时把查找参数keyword置空,编写如下代码:

// 数据模型select翻滚触底时触发分页接口拜访
const isGettingSceneModelList = ref(true); // 整个select的loading控制变量
const sceneModelList = ref<TDataModelList>([]); // 寄存下拉列表
const isScrollLoading = ref(false); // loading控制变量(在select-option最下面放了一个loading)
const noMoreData = ref(false); // 标识后端是否现已没有数据了
let page = 1;
const size = 20;
let keyword = '';
​
// 翻滚触底回调, 对应select的scroll-bottom事情
const selectScrollBottom = async () => {
 if (noMoreData.value) return; // 假如noMoreData为true, 则没必要触发函数体履行return即可
 isScrollLoading.value = true; // 展现最下面的loading
 page += 1; // 恳求下一页的数据(追加至List列表)
 const params = {
  page,
  size,
  keyword,
  };
 const [error, res] = await to(getSceneModelList(params));
 if (error) {
  return Message({ message: error.message, type: 'error' });
  }
 // 假如后端无数据回来, noMoreData置为true
 if (res.data.items === null || res.data.items.length === 0) {
  isScrollLoading.value = false; // 下拉列表最下面的loading完毕
  noMoreData.value = true;
  return;
  }
 // 追加后端回来的数据至list
 sceneModelList.value = [...sceneModelList.value, ...(res.data.items || [])];
 isScrollLoading.value = false; // 下拉列表最下面的loading完毕
};

实现select支持长途查找

说白了咱们需要保护用户的输入,即keyword变量,当查找时更新keyword这个恳求参数,失掉焦点时清空即可。

调配select组件的filterable = "true"即敞开输入查找, remote = "true" (默认为false,即针对列表内的数据进行查找)即调用remote-method 指定的办法进行查找(或者说用户输入时详细履行的逻辑全由remote-method决定了),remote-method = "getSceneModelListByKeyword"即用户输入时履行的回调函数。

编写getSceneModelListByKeyword函数如下:

// 长途查找回调
const getSceneModelListByKeyword = async (input = '') => {
 page = 1;
 keyword = input; // 更新外层的keyword, 因为此时的分页恳求也是基于当时用户输入的keyword进行查找的
 isGettingSceneModelList.value = true; // 查找时整个select置为loading态
 const params = {
  page,
  size,
  keyword,
  };
 const [error, res] = await to(getSceneModelList(params));
 if (error) {
  return Message({ message: error.message, type: 'error' });
  }
 // 更新list为查找到的数据
 sceneModelList.value = res.data.items || [];
 isGettingSceneModelList.value = false;
};
// 组件挂载之前调用一次getSceneModelListByKeyword, 获取初始数据, 其实也能够借助触底办法来获取初始数据, 但是触底办法控制的loading是下拉列表最底部的, 而非整个select的loading, 所以调用长途查找办法获取初始数据最为合适
getSceneModelListByKeyword();
// 失掉焦点时清空查找要害词keyword
const onBlur = () => {
 keyword = '';
};