vue实现@唤起列表功能(借助ElAutocomplete)

实现一个输入组件

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值