实现一个输入组件
myAutoComplete.vue
<template>
<el-autocomplete ref="autoRef" :model-value="state" @input="handleInput" :onkeyup="handleKey"
:fetch-suggestions="querySearch" @select="handleSelect" :select-when-unmatched="true" placeholder="Please Input">
<template #prepend>
<slot name="prepend">
</slot>
</template>
</el-autocomplete>
</template>
<script setup lang="ts">
import { connectData } from '@/api/modules/word';
const state = ref('');
const props = defineProps(['modelValue'])
const emits = defineEmits(['update:modelValue'])
const range = ref(0)//光标位置
onMounted(() => {
console.log(props.modelValue)
state.value = props.modelValue ? props.modelValue : ''
})
watch(state, (val) => {
if (val.charAt(val.length - 1) === '@') {
return
}
emits('update:modelValue', state.value)
})
const restaurants = connectData.data.records.map((item: any) => {
return {
value: '@' + item.aliasZh,
address: item.aliasZh,
};
});
const querySearch = (queryString: string, cb: Function) => {
queryString = queryString.substring(0, range.value)
const query = '@' + queryString.split('@')[queryString.split('@').length - 1]
const results = queryString
? restaurants.filter((restaurant: any) => restaurant.value.includes(query))
: restaurants;
// 调用 callback 返回建议列表的数据
cb(results);
};
const autoRef = ref()
const handleSelect = (item: any) => {
const modelvalue = props.modelValue ? props.modelValue : ''
//删除@符号和之后的内容
const index1 = modelvalue.lastIndexOf('@')
const index2 = modelvalue.lastIndexOf('}')
const last = modelvalue.substring(range.value)
if (index1 !== -1 && index2 !== -1 && index1 > index2) {
state.value = modelvalue.substring(0, index1) + '{' + item.value + '}' + last
nextTick(() => {
autoRef.value.inputRef.input.selectionStart = index1 + item.value.length + 2
autoRef.value.inputRef.input.selectionEnd = index1 + item.value.length + 2
})
return
}
state.value = modelvalue.substring(0, range.value - 1) + '{' + item.value + '}' + modelvalue.substring(range.value)
nextTick(() => {
autoRef.value.inputRef.input.selectionStart = range.value + item.value.length + 1
autoRef.value.inputRef.input.selectionEnd = range.value + item.value.length + 1
})
}
const handleInput = (val: string) => {
state.value = val
}
const handleKey = (event: any) => {
range.value = event.target.selectionStart
}
</script>
在页面使用
<myAutoComplete v-model="data.label" style="width: 100%;">
<template #prepend>
<el-button :icon="NodeIcon(data)" />
</template>
</myAutoComplete>