基于elementUI的el-autocomplete组件的自动补全下拉框实践

html 复制代码
<template>
  <div :class="$options.name">
    <el-autocomplete
      style="width: 100%"
      ref="autocomplete"
      :popper-class="`${$options.name}-el-autocomplete`"
      v-model="inputSearchValue"
      :placeholder="`输入关键词...`"
      :value-key="`label`"
      :fetch-suggestions="fetchSuggestions"
      :hide-loading="false"
      :debounce="0"
      @focus="focusAutocomplete"
      @select="selectSuggestionsItem"
      @clear="focusAutocomplete"
      clearable
    >
      <template slot-scope="{ item }">
        <div>
          <span class="label" v-html="item.highlightLabel || item.label" />
          <span
            class="value"
            style="
              margin-left: 5px;
              line-height: 20px;
              color: #999;
              border-radius: 88px;
              background-color: #eee;
              box-sizing: border-box;
              padding: 0px 10px;
            "
            >{{ item.value }}</span
          >
        </div>
      </template>
      <el-button slot="append" icon="el-icon-search" @click="clickSearchIcon"></el-button>
    </el-autocomplete>
  </div>
</template>
<script>
export default {
  name: `autocompleteInput`,
  components: {},
  data() {
    return {
      inputSearchValue: "",
      searchItems: [
        { value: 1, label: "显示文本1" },
        { value: 2, label: "显示文本2" },
        { value: 3, label: "显示文本3" },
        { value: 4, label: "显示文本4" },
        { value: 5, label: "显示文本5" },
      ],
    };
  },

  props: ["value", "data"],

  watch: {
    data: {
      handler(newValue, oldValue) {
        if (Object.keys(newValue || {}).length) {
          if (newValue.ID) {
            this.inputSearchValue =
              (this.searchItems.find((v) => v.ID == newValue.ID) || {}).label ||
              newValue.label ||
              "";
          }
        }
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
  },
  created() {},
  mounted() {},
  beforeDestroy() {},
  methods: {
    focusAutocomplete() {
      this.$nextTick(() => {
        this.$refs.autocomplete.focus();
        this.$refs.autocomplete.$el.querySelector("input").select();
        this.$refs.autocomplete.activated = true; //这句话是重点(触发下拉框出现)
      });
    },
    fetchSuggestions(queryString, callback) {
      if (!queryString) return callback(this.searchItems); //如果没有输入内容就提供最频繁使用的备选项;
      let qs = queryString.trim().toLocaleLowerCase();
      let searchItems = JSON.parse(JSON.stringify(this.searchItems));
      let r = searchItems.filter((v, i, ar) => {
        // 如果内容文本or速记符包含了输入关键词
        if (
          v.label.toLocaleLowerCase().includes(qs) ||
          (v.SJF || "").toLocaleLowerCase().includes(qs)
        ) {
          let highlightLabel = `<b style='color:#409EFF;font-weight:bold;'>${queryString}</b>`;
          v.highlightLabel = v.label.replace(
            new RegExp(queryString, "gi"),
            highlightLabel
          );
          return v;
        }
      }); //从searchItems中搜索结果
      let perfectMatch = this.searchItems.find((v) => v.label === queryString);
      if (perfectMatch) {
        this.$emit(`s`, perfectMatch); //没有点击下拉框触发获取完全匹配项
      } else if (r.length === 0) {
        this.$emit(`s`, { ID: null, label: queryString }); //没有找到匹配项
      }
      callback(r);
    },
    selectSuggestionsItem(d) {
      this.$emit(`s`, d);
    },
    clickSearchIcon(d) {
      this.focusAutocomplete();
      this.$emit(`search`, d);
    },
  },
};
</script>
<style lang="scss" scoped>
.autocompleteInput {
}
</style>

el-autocomplete那些在饿了么官方文档看不到的API_el-autocomplete activated-CSDN博客文章浏览阅读469次。在Vue的Autocomplete组件中,通过设置`activated`属性为`true`和使用`suggestions`可以直接触发下拉框内容更新。当点击清除按钮后,结合`$nextTick`确保焦点重新回到输入框并显示下拉框建议。https://blog.csdn.net/qq_37860634/article/details/130884352【sgAutocomplete】自定义组件:基于elementUI的el-autocomplete组件开发的自动补全下拉框组件(带输入建议的自动补全输入框)_elautocomplete自定义-CSDN博客文章浏览阅读1.2k次,点赞10次,收藏9次。1、支持本地保存选中过的记录2、支持动态接口获取匹配下拉框内容3、可以指定对应的显示label和字段组件key。_elautocomplete自定义https://blog.csdn.net/qq_37860634/article/details/134851806