特性:
1、支持本地保存选中过的记录
2、支持动态接口获取匹配下拉框内容
3、可以指定对应的显示label和字段组件key
4、自动生成速记符字段(包含声母和全拼两种类型),增强搜索匹配效率
sgAutocomplete源码
<template><!-- 基于elementUIel-autocomplete组件开发的自动补全下拉框组件 --><el-autocomplete:class="$options.name"style="width: 100%"ref="autocomplete":popper-class="'sgAutocomplete-el-autocomplete'"v-model="inputSearchValue":placeholder="placeholder || `输入关键词…`":value-key="valueKey || `label`":fetch-suggestions="fetchSuggestions":hide-loading="false"@focus="$refs.autocomplete.$el.querySelector('input').select()"@select="selectSuggestionsItem"@clear="focusAutocomplete":debounce="0"clearable><template slot-scope="{ item }"><div><i v-if="item.isHistory" class="history-icon el-icon-time" /><span class="label">{{ item[labelKey || `label`] }}</span></div></template><!-- 搜索按钮1 --><i class="el-icon-search el-input__icon" slot="suffix" v-if="showSearchButton == 1" /><!-- 删除历史记录按钮 --><i:title="clearHistoryTitle || `删除历史记录`"class="el-icon-delete el-input__icon clearHistory"slot="suffix"v-if="showHistoryBtn"@click="clearHistory"/><!-- 搜索按钮2 --><el-buttonslot="append"icon="el-icon-search"@click="focusAutocomplete"v-if="showSearchButton == 2"></el-button></el-autocomplete>
</template><script>
import pinyin from "@/js/pinyin";
export default {name: "sgAutocomplete",components: {},data() {return {inputSearchValue: null,historyListLocalStorageName: null, //保存到本地记录的localStorage KeysearchItems: [],showHistoryBtn: false,};},props: ["data", //可选项数组(必选参数)"value","valueKey", //获取值"labelKey", //显示值"placeholder","clearHistoryTitle", //删除历史记录按钮提示"filterKeys", //匹配搜索的字段(数组)不传此参数默认就用labelKey"showHistory", //显示历史选择记录"showSearchButton", //显示搜索按钮(样式:1 是在输入框里面的icon,2 是在输入框后面的按钮)"autofocus",],watch: {data: {handler(newValue, oldValue) {if (newValue && Object.keys(newValue).length) {this.searchItems = JSON.parse(JSON.stringify(newValue));this.searchItems.forEach((v) => {v.SJF = pinyin.getCamelChars(v[this.labelKey || "label"]); //速记符(声母)v.SJF_full = pinyin.getFullChars(v[this.labelKey || "label"]); //速记符(全拼)});}},deep: true, //深度监听immediate: true, //立即执行},value: {handler(newValue, oldValue) {this.inputSearchValue = newValue;},deep: true, //深度监听immediate: true, //立即执行},inputSearchValue: {handler(newValue, oldValue) {this.$emit(`input`, newValue);},deep: true, //深度监听immediate: true, //立即执行},showHistory: {handler(newValue, oldValue) {this.historyListLocalStorageName = newValue;},deep: true, //深度监听immediate: true, //立即执行},},mounted() {(this.autofocus === "" || this.autofocus) && this.focusAutocomplete(); //默认聚焦},methods: {focusAutocomplete(d) {this.$nextTick(() => {this.$refs.autocomplete.focus();this.$refs.autocomplete.activated = true; //这句话是重点});},// 搜索下拉框fetchSuggestions(queryString, callback) {if (queryString) {queryString = queryString.toString().trim();let r = this.searchItems.filter((v, i, ar) => {let filterKeys = this.filterKeys || [this.labelKey];filterKeys.push("SJF", "SJF_full"); //自动匹配声母、全屏组合return filterKeys.some((filterKey) =>v[filterKey].toLocaleLowerCase().includes(queryString.toLocaleLowerCase()));});this.showHistoryBtn = false;callback(r);} else {let historys = this.getHistorys();historys.forEach((v) => (v.isHistory = true)); //标识是历史记录this.showHistoryBtn = historys.length > 0;callback(historys);}},selectSuggestionsItem(d) {let historys = this.getHistorys();if (historys.length) {let k = this.valueKey || this.labelKey || "label";let has = historys.some((v) => v[k] == d[k]);has || historys.unshift(d);localStorage[this.historyListLocalStorageName] = JSON.stringify(historys);} else {localStorage[this.historyListLocalStorageName] = JSON.stringify([d]);}this.$emit(`change`, d);},getHistorys() {let historys = localStorage[this.historyListLocalStorageName];return JSON.parse(historys || "[]");},clearHistory(d) {delete localStorage[this.historyListLocalStorageName];this.showHistoryBtn = false;this.focusAutocomplete();},},
};
</script><style lang="scss" scoped>
.sgAutocomplete {.clearHistory {cursor: pointer;&:hover {color: #409eff;}}
}
</style>
里面用到的pinyin.js在这篇文章里面JS自动生成速记符、拼音简写/拼音的声母(例如:“你挚爱的强哥”转换为“NZADQG”)。提取首字母,返回大写形式;提取拼音, 返回首字母大写形式(全拼)。_你挚爱的强哥的博客-CSDN博客文章浏览阅读2.7k次。需要引用以下pinyin.js文件。https://blog.csdn.net/qq_37860634/article/details/130765296
用例
<template><div><sgAutocompleteautofocusv-model="sgAutocompleteValue":data="data":placeholder="`输入搜索关键词...`":valueKey="`value`":labelKey="`label`"showHistory="localStorageHistoryName"showSearchButton="2"@change="changeSgAutocomplete"/><p style="margin-top: 20px">选择的数据:{{ sgAutocompleteValue }}</p><pstyle="margin-top: 20px;word-wrap: break-word;word-break: break-all;white-space: break-spaces;"><span>选择的对象:</span>{{ sgAutocompleteObject ? JSON.stringify(sgAutocompleteObject, null, 2) : "" }}</p></div>
</template>
<script>
import sgAutocomplete from "@/vue/components/admin/sgAutocomplete";
export default {components: { sgAutocomplete },data() {return {sgAutocompleteValue: null,sgAutocompleteObject: null,data: [],//模拟数据1dataA: [{ value: "1", label: "A显示文本1" },{ value: "2", label: "A显示文本2" },{ value: "3", label: "A显示文本3" },{ value: "4", label: "A显示文本4" },{ value: "5", label: "A显示文本5" },],//模拟数据2dataB: [{ value: "1", label: "B显示文本1" },{ value: "2", label: "B显示文本2" },{ value: "3", label: "B显示文本3" },{ value: "4", label: "B显示文本4" },{ value: "5", label: "B显示文本5" },],};},watch: {// 模拟动态更新筛选项sgAutocompleteValue: {handler(newValue, oldValue) {if (newValue && Object.keys(newValue).length) {switch (newValue.toLocaleLowerCase()) {case "a":this.data = this.dataA;break;case "b":this.data = this.dataB;break;}}},},},methods: {changeSgAutocomplete(d) {this.sgAutocompleteObject = d;},},
};
</script>