共计 3479 个字符,预计需要花费 9 分钟才能阅读完成。
本文记录一下 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 什么的传递给后端,那么这个时候,传递多个参数就是必须滴了,这个时候应用上述闭包的形式就能解决问题啦