需求产生原因
在日常业务开发当中,经常性地会用到 el-input 及 el-select 作为 筛选项 组件
二者均有不足之处。前者 无法提供建议,后者 无法模糊搜索
那么,是否有兼顾二者优势的组件?
通过检索 Element-UI 官方文档,竟发现 el-input 使用引导下,隐藏着另一组件 el-autocomplete
所存在的不足及处理方法
下述处理,均在 继承el-autocomplete组件 基础上实现(继承相关内容可参照 Element组件全局调整)
与调整相关源代码:
handleClear() {
this.activated = false;
this.$emit('clear');
},
handleKeyEnter(e) {
if (this.suggestionVisible && this.highlightedIndex >= 0 && this.highlightedIndex < this.suggestions.length) {
e.preventDefault();
this.select(this.suggestions[this.highlightedIndex]);
} else if (this.selectWhenUnmatched) {
this.$emit('select', {value: this.value});
this.$nextTick(_ => {
this.suggestions = [];
this.highlightedIndex = -1;
});
}
},
select(item) {
this.$emit('input', item[this.valueKey]);
this.$emit('select', item);
this.$nextTick(_ => {
this.suggestions = [];
this.highlightedIndex = -1;
});
},
handleChange(value) {
this.$emit('change', value);
},
handleClear 为Input输入框值清空时的回调函数
handleKeyEnter 为监听Enter按键按下时的回调事件
select 为针对选中项的具体操作内容
未选择建议项,按下Enter键后,未隐藏输入建议框
问题复现
处理代码
handleKeyEnter(e) {
if (this.suggestionVisible && this.highlightedIndex >= 0 && this.highlightedIndex < this.suggestions.length) {
xxx
} else if (this.selectWhenUnmatched) {
xxx
} else {
// 无匹配项 且 回车不触发select事件 情况下
this.$nextTick(_ => {
// 延时180ms。避免快速输入、按击Enter键后,意外重现输入建议框
setTimeout(() => {
// 增补内容(输入框失焦、输入建议清空)
this.$refs.input.blur();
this.suggestions = [];
}, 180)
})
}
}
通过键盘选中时,未触发change事件
处理代码
select(item) {
xxx
// 手动触发(源代码中对change事件触发做了进一步封装)
this.handleChange(item[this.valueKey])
xxx
},
// 配合select方法中的调整,避免短时间内发起重复请求
handleChange: debounce(16, function (value) {
this.$emit('change', value)
}),
在输入框聚焦状态下,清空数据后,未失焦
情况复现
处理代码
handleClear() {
xxx
// 增补内容(输入框失焦)
this.$refs.input.blur();
}
完整代码及应用示例
完整内容
import { Autocomplete } from 'element-ui'
import debounce from 'throttle-debounce/debounce'
const AutocompletePatch = {
extends: Autocomplete,
methods: {
handleClear() {
this.activated = false
this.$emit('clear')
// 增补内容(输入框失焦)
this.$refs.input.blur()
},
handleKeyEnter(e) {
if (
this.suggestionVisible &&
this.highlightedIndex >= 0 &&
this.highlightedIndex < this.suggestions.length
) {
e.preventDefault()
this.select(this.suggestions[this.highlightedIndex])
this.$nextTick((_) => {
// 增补内容(输入框失焦)
this.$refs.input.blur()
})
} else if (this.selectWhenUnmatched) {
this.$emit('select', { value: this.value })
this.$nextTick((_) => {
this.suggestions = []
this.highlightedIndex = -1
})
} else {
// 无匹配项 且 回车不触发select事件 情况下
this.$nextTick((_) => {
setTimeout(() => {
// 增补内容(输入框失焦、输入建议清空)
this.$refs.input.blur()
this.suggestions = []
}, 180)
})
}
},
select(item) {
this.$emit('input', item[this.valueKey])
this.$emit('select', item)
// 增补内容(选中时,同时触发change事件)
this.handleChange(item[this.valueKey])
this.$nextTick((_) => {
this.suggestions = []
this.highlightedIndex = -1
})
},
// 配合select方法中的调整,避免短时间内发起重复请求
handleChange: debounce(16, function (value) {
this.$emit('change', value)
}),
},
}
export default {
install(Vue) {
Vue.component(Autocomplete.name, AutocompletePatch)
}
}
应用示例
<el-autocomplete
v-model="**绑定的参数**"
clearable
placeholder="请输入"
:fetch-suggestions="
(query, cb) => fetchSuggestions(**待建议数据集合**, query, cb)
"
@change="**回调函数**"
/>
fetchSuggestions(list, query, cb) {
const filterValues = query
? list.filter((item) => item.includes(query))
: list
const results = filterValues.map((value) => {
return { value }
})
cb(results)
}