实现一个输入组件
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 + '}' + lastnextTick(() => {autoRef.value.inputRef.input.selectionStart = index1 + item.value.length + 2autoRef.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 + 1autoRef.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>