欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > 封装el-autocomplete,接口调用

封装el-autocomplete,接口调用

2025/4/28 14:18:55 来源:https://blog.csdn.net/irisMoon06/article/details/147566956  浏览:    关键词:封装el-autocomplete,接口调用

组件

<template><el-autocompletev-model="selectedValue":fetch-suggestions="fetchSuggestions":placeholder="placeholder"@select="handleSelect"clearablev-bind="$attrs"/>
</template><script lang="ts" setup>
import { ref, computed, onMounted, withDefaults } from 'vue'
import type { AutocompleteProps, AutocompleteEmits } from 'element-plus'interface AutocompleteItem {value: string[key: string]: any
}interface Props {placeholder?: stringdebounce?: numberapiFn?: (query: string) => Promise<AutocompleteItem[]> // 模拟接口函数localData?: AutocompleteItem[] // 本地数据filterFn?: (query: string, item: AutocompleteItem) => boolean // 自定义过滤函数
}const props = withDefaults(defineProps<Props>(), {placeholder: '请输入内容',debounce: 300,localData: () => [],filterFn: undefined
})const emit = defineEmits<{(e: 'update:modelValue', value: string): void(e: 'select', item: AutocompleteItem): void
}>()const selectedValue = ref('')
const loading = ref(false)
const suggestions = ref<AutocompleteItem[]>([])
let timeout: number | undefined// 默认过滤函数 - 开头匹配(不区分大小写)
const defaultFilter = (query: string) => {const lowerQuery = query.toLowerCase()return (item: AutocompleteItem) => item.value.toLowerCase().startsWith(lowerQuery)
}// 模拟接口获取数据
const mockApiFetch = async (query: string): Promise<AutocompleteItem[]> => {// 这里模拟API请求延迟await new Promise(resolve => setTimeout(resolve, 500))// 模拟数据const mockData = [{ value: 'Vue', link: 'https://vuejs.org' },{ value: 'React', link: 'https://reactjs.org' },{ value: 'Angular', link: 'https://angular.io' },{ value: 'Svelte', link: 'https://svelte.dev' },{ value: 'TypeScript', link: 'https://www.typescriptlang.org' },]// 模拟接口过滤return mockData.filter(item => item.value.toLowerCase().includes(query.toLowerCase()))
}// 获取建议列表
const fetchSuggestions = async (query: string, cb: (arg: AutocompleteItem[]) => void
) => {clearTimeout(timeout)if (!query) {cb(props.localData)return}loading.value = truetimeout = setTimeout(async () => {try {let results: AutocompleteItem[] = []if (props.apiFn) {// 使用传入的接口函数获取数据results = await props.apiFn(query)} else if (props.localData.length) {// 使用本地数据过滤const filter = props.filterFn ? (item: AutocompleteItem) => props.filterFn!(query, item): defaultFilter(query)results = props.localData.filter(filter)} else {// 使用默认模拟接口results = await mockApiFetch(query)}suggestions.value = resultscb(results)} catch (error) {console.error('获取建议列表失败:', error)cb([])} finally {loading.value = false}}, props.debounce) as unknown as number
}// 选择事件
const handleSelect = (item: AutocompleteItem) => {emit('update:modelValue', item.value)emit('select', item)
}// 暴露方法
defineExpose({focus: () => {// 这里可以访问el-autocomplete的方法// 需要在实际使用时通过ref获取组件实例}
})
</script><style scoped>
.el-autocomplete {width: 100%;
}
</style>

基本用法(使用内置模拟接口)

<template><CustomAutocomplete v-model="selectedValue" />
</template><script setup lang="ts">
import { ref } from 'vue'
import CustomAutocomplete from './CustomAutocomplete.vue'const selectedValue = ref('')
</script>

使用自定义接口函数

<template><CustomAutocomplete v-model="selectedValue":api-fn="fetchDataFromApi"/>
</template><script setup lang="ts">
import { ref } from 'vue'
import CustomAutocomplete from './CustomAutocomplete.vue'const selectedValue = ref('')const fetchDataFromApi = async (query: string) => {// 这里可以替换为真实的API调用console.log('查询:', query)return [{ value: `${query}-结果1`, id: 1 },{ value: `${query}-结果2`, id: 2 }]
}
</script>

自定义过滤逻辑

<template><CustomAutocomplete v-model="selectedValue":local-data="techList":filter-fn="customFilter"/>
</template><script setup lang="ts">
import { ref } from 'vue'
import CustomAutocomplete from './CustomAutocomplete.vue'const selectedValue = ref('')
const techList = ref([{ value: 'Vue.js', category: 'frontend' },{ value: 'React', category: 'frontend' },{ value: 'Express', category: 'backend' }
])const customFilter = (query: string, item: any) => {// 同时匹配value和categoryreturn item.value.toLowerCase().includes(query.toLowerCase()) || item.category.toLowerCase().includes(query.toLowerCase())
}
</script>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词