本文记录一下el-autocomplete的使用和两个常见的问题
需求分析
假设我们有这样的一个需求:
- 当用户在输入框中输入内容后,呈现关联建议可选项信息,以供用户选择.比如用户输入了“王”这个字,那么要呈现关于“王”的所有的信息,什么“老王”、“王老吉"都出来了,用户点关联的建议可选项,从而方便用户快速输入。
- 初始情况下,当用户的input输入框获得焦点的时候,与此同时,input输入框中的内容也是没有的时候,就呈现用户之前搜索过得历史记录。
- 当用户输入了一些文字但是又backspace一个个删除掉了的时候,即当用户把输入框中的文字删除完以后的时候,也就是input输入框的内容为空的时候,再次呈现历史记录
这个时候使用el-autocomplete组件就可以快速解决我们的问题了
el-autocomplete属性介绍
fetch-suggestions属性
绑定的是函数,函数的触发条件是当input输入的时候,或者用户在进入框键入字以后都会触发的,正常情况下回调函数的参数有两个,分别是queryString、和cb。queryString参数代表的值是用户填写到input输入框中的数据值,而cb指的又是一个函数,这里是高阶函数(柯里化)的用法,这里不赘述。cb函数接收的是一个数组,数组里是啥,input输入框关联出现的下拉框就是啥,一一对应的。不过有固定格式要求。因为在el-autocomplete的底层代码里,是有着v-for循环指令的,至于循环的数组就是cb函数传递过来的数组,所以cb函数中的数组内容,也就是输入建议的下拉框的内容
// html部分
:fetch-suggestions="querySearch"
// js部分
querySearch(queryString, cb) {
cb([
{value:"老王"},
{value:"王老吉"} // 数组中的每一项都是一个对象,对象中必须要有value属性,否则不能显示,有没有别的属性不影响。原因是因为源码中定义的就是value字段
])
}
// 如果后端给的数据结构不是这种的结构的话,可以使用数组的filter或者map方法自己组装一下数据结构格式
图示如下:
fetch-suggestions也可以传递多个数据,不过要使用闭包的形式才可以,这个后文会举例子再说的。
fetch-suggestions,是用来做关联的数据搜索,用户输入“王”字,获取关联的“老王”、“王老吉”选项值,当用户选中王老吉的时候,如果是一个搜索功能,就需要搜索王老吉的具体资料了,所以这个时候就需要使用el-autocomplete的select属性了
select属性
select绑定的也是一个函数方法,当我们点击选择input输入框关联下拉框某个选项的时候,会拿到下拉框对应项的值。这个值可以传递给后端,用于向后端发请求查询选中的某一条数据的具体信息。
// html部分
@select="handleSelect"
// js部分
handleSelect(item) { // 参数-选中的某一项
console.log("拿到数据作为参数去向后端发请求",item);
}
trigger-on-focus属性
这个属性的作用是,控制fetch-suggestions是否在el-input获取焦点的时候触发。只要fetch-suggestions触发,就会向后端发请求,就会出现input输入框关联下拉框(输入建议列表),官方定义的是默认为:trigger-on-focus=true,就是输入框输入框一获取焦点,就出现输入建议列表,trigger-on-focus="true"这种方式可以用在获取历史搜索数据场景,毕竟初始情况下可以让后端提供一下历史数据以供用户选择。
当然如果是设置trigger-on-focus="false"的话,这样就不会在初始情况获取焦点的时候出现输入建议列表,在用户输入文字以后才去拿着用户在输入框输入的东西去发请求,问后端要数据。
具体用那种看具体需求。
我们先看一下效果图,再看一下代码
效果图
代码附上
<template>
<div id="box">
<el-autocomplete
:fetch-suggestions="querySearch"
v-model="inputValue"
@select="handleSelect"
:debounce="0"
:trigger-on-focus="true"
clearable
@clear="blurForBug()"
></el-autocomplete>
</div>
</template>
<script>
export default {
data() {
return {
inputValue: "",
};
},
methods: {
//输入框获取焦点时调用的方法
querySearch(queryString, cb) { // queryString是用户输入的想要查询的内容,cb是回调函数(可以发请求获取数据)
console.log("如何触发", queryString, cb);
if (queryString == "") {
cb([{ value: "历史记录一" }, { value: "历史记录二" }]); // 当然这里的历史记录是后端返给我们的,应该为接口返回的数据
} else {
let apiResult = [
{
value: "老王",
},
{
value: "王老吉",
},
];
// 这里我们模拟从后端的接口异步获取的数据
setTimeout(() => {
// cb([]) cb函数如果返回一个空数组的话,那个模糊搜索输入建议的下拉选项因为length为0就会消失了
cb(apiResult);
}, 500);
}
},
// 选中输入框推荐的值的时候触发
handleSelect(item) { // 参数
console.log("拿到数据", item);
},
// 点击clearable清空小图标按钮以后,继续重新在输入框中输入数据,querySearch会触发,但是cb函数不会触发
// 这样的话就会出现发请求了,也获取数据了,但是input框的输入建议下拉框不呈现在页面上的问题,所以解决方法就是
// 只要用户点击了
blurForBug(){
document.activeElement.blur()
}
},
};
</script>
<style lang="less" scoped>
#box {
width: 100%;
height: 600px;
box-sizing: border-box;
padding: 50px;
}
</style>
常见问题
点击 clearable清除按钮输入建议失效
我们会发现,如果给el-autocomplete组件标签加上clearable属性以后,那么,当我们输入内容以后,再点击clearable清空按钮清空输入框中输入的数据以后,当我们再重新输入文字的时候,请求会触发,后端返给我们的数据也获取到了,但是后端返回给我们的数据却没有渲染到页面上。就仿佛输入没反应了。解决方案比较直接的就是,当用户点击了clearable清空按钮以后,就让当前获取焦点的输入框失去焦点,回到最初状态,一切重新开始
即为:主动触发失去焦点,解决‘fetch-suggestions’输入建议失效的bug,也就是:@clear="blurForBug()"
传递多个参数(使用闭包)
html部分
<el-autocomplete
v-model="inputValue"
@select="handleSelect"
:debounce="0"
:trigger-on-focus="true"
clearable
@clear="blurForBug()"
:fetch-suggestions="
(queryString, cb) => {
multipleFn(queryString, cb, index);
}
"
></el-autocomplete>
js部分
multipleFn(queryString, cb, index) {
console.log(queryString, cb, index)
}
注意上述html部分中的:fetch-suggestions的写法,这里使用闭包的写法,这样的话,就可以传递多个参数了。因为如果某个功能模块有好多个el-autocomplete,这样的话,我们就要使用v-for去循环出来,可能需要把item,index什么的传递给后端,那么这个时候,传递多个参数就是必须滴了,这个时候使用上述闭包的方式就能解决问题啦
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。