组件开发--el-select下拉框添加分页(可搜索)

1,000 阅读2分钟

2024.8.2

需求描述:

select下拉框的数据,是通过另外一个分页接口获取到的,因为数据过多,起初想做一个点击弹框显示列表内容,后想着因为展示的内容只需要name+id,所以选择下拉框中添加分页,并且可搜索。

效果图如下

image.png

image.png

代码部分

home.vue

<template>
    <el-form-item :required="true" label="文件配置ID" prop="fileConfigId">
        <SelectPage
            v-model="formData['fileConfigId']"
            :getListApi="getfileRulesList"
            :optionsFunc="optionsFunc"
            searchKey="fileConfigId"
            label="文件配置ID"
        />
    </el-form-item>
</template>

<script setup lang="ts">
    import { getfileRulesList } from '@/api/service/task'
    
    const optionsFunc = (list: any) => {
        return list.map((item: any) => {
            return {
                label: `${item.fileConfigId}${item.configName}】`,
                value: item.fileConfigId,
            }
        })
    }
</script>

components/SelectPage.vue

<template>
    <el-select
        v-model="selectValue"
        :loading="loading"
        :placeholder="placeholder ? placeholder : `请选择${label}`"
        :disabled="disabled"
        :fit-input-width="true"
        filterable
        clearable
        :filter-method="remoteMethod"
        @change="handleChange"
    >
        <template #default>
            <el-option
                v-for="stems in options"
                :key="stems[valueKey]"
                :value="stems[valueKey]"
                :label="stems[labelKey]"
            />
        </template>

        <template #footer>
            <TablePagination
                :pageNum="pageable.pageNum"
                :pageSize="pageable.pageSize"
                :total="pageable.total"
                :on-current-change="handleCurrentChange"
                layout="prev, pager, next"
                :small="true"
                :background="false"
            />
        </template>
    </el-select>
</template>

<script setup lang="ts">
import { ref, onBeforeMount, computed } from 'vue'
import TablePagination from '@/components/TablePagination/index.vue'

interface ListItem {
    value: string
    label: string
}

interface Props {
    modelValue: string //el-select的v-model
    getListApi: (params: object) => Promise<any>
    optionsFunc: (list: Array<any>) => [] //options数据重组的方法 传入list 返回数组
    searchKey?: string //	搜索条件查询key
    valueKey?: string //	传入的 option 数组中,要作为最终选择项的键值 key
    labelKey?: string //	传入的 option 数组中,要作为显示项的键值名称
    disabled?: boolean //是否禁用
    placeholder?: string //placeholder
    label?: string //label
}

const props = withDefaults(defineProps<Props>(), {
    modelValue: '',
    valueKey: 'value',
    labelKey: 'label',
    disabled: false,
    searchKey: '',
})
const emits = defineEmits(['update:modelValue']) //v-model双向绑定方法
const selectValue = computed({
    //v-model 通过computed方法实时监听
    get() {
        return props.modelValue
    },
    set(val) {
        emits('update:modelValue', val)
    },
})
const loading = ref(false) //加载
const options = ref<ListItem[]>([]) //下拉选项
const selectData = ref(selectValue.value || '') //列表查询条件 编辑状态时等于初始值selectValue,此时options列表可以定位到选中内容
//分页
const pageable = ref({
    pageNum: 1,
    pageSize: 20,
    total: 0,
})

onBeforeMount(() => {
    getList()
})
//获取option数据
const getList = () => {
    let params = {
        ...pageable.value,
    }
    if (props.searchKey) {
        params = {
            ...params,
            [props.searchKey]: selectData.value,
        }
    }
    console.log(params, 'params')
    loading.value = true
    props?.getListApi(params).then((res) => {
        const optionsList = props.optionsFunc(res.data.list)
        //list.value.filter((item) => {
        //     return item.label.toLowerCase().includes(query.toLowerCase())
        //   })
        options.value = JSON.parse(JSON.stringify(optionsList))
        pageable.value.total = res.data.total
        loading.value = false
    })
}

//模糊查询 远程查询
const remoteMethod = (query: string) => {
    if (query) {
        selectData.value = query
        getList()
    }
}

//点击当前页面
const handleCurrentChange = (val: number) => {
    pageable.value.pageNum = val
    getList()
}
//clearable 为true 点击清除按钮时触发
const handleChange = (value: string) => {
    if (!value) {
        handleCurrentChange(1)
    }
}
</script>

参考文献