封装组件代码
<template>
<el-select v-bind="$attrs" :remote-method="remoteMethod">
<div v-infinite-scroll="loadMore" style="overflow: hidden">
<el-option v-for="dict in list" :key="dict.value" :label="dict.label" :value="dict.value" />
</div>
</el-select>
</template>
<script lang="ts" setup name="ScorllSelect">
import { ref } from 'vue'
import { debounce } from '@/utils/index'
interface Item {
value: number,
label: string
}
const props = defineProps({
// 传入对应的列表加载api
methods: {
type: Function,
default: ''
},
// 传入查询关键字
searchKey: {
type: String,
default: ''
}
})
const list = ref<Item[]>([])
const queryFrom = ref({
page: 1,
totlePage: 1,
pageSize: 10
})
// 自定义远程搜索方法
const remoteMethod = (query: string) => {
queryFrom.value.page = 1
list.value = []
queryFrom.value[props.searchKey] = query
getList()
}
// 调用props.methods获取下拉数据
const getList = () => {
props.methods(queryFrom.value).then(res => {
list.value = [...list.value, ...res.rows]
queryFrom.value.totlePage = Math.ceil(res.total / 10)
})
}
// 获取初始数据
getList()
// 无限滚动触底加载
const loadMore = debounce(() => {
if (queryFrom.value.page >= queryFrom.value.totlePage) return
queryFrom.value.page++
getList()
}, 200)
</script>
父组件中使用
<ScorllSelect
v-if="isMounted"
v-model="queryParams.xxx"
placeholder="请选择"
clearable
style="width: 160px"
filterable
remote
searchKey="searchKey"
:methods="getList">
</ScorllSelect>
<script setup>
import { ref, onMounted } from "vue";
import { getList } from "@/api/xxx/xxx";
import ScorllSelect from "@/components/ScrollSelect.vue";
const isMounted = ref(false);
onMounted(() => {
isMounted.value = true;
});
</script>