Vueelement-ui远程搜索输入框
Vue+element-ui远程搜索输入框
这段时间在自我摸索过程中遇到的一些问题,整理了一下,在这里跟大家一起分享一下自己的踩坑过程,以供借鉴,下面直接先上效果图。
文章目录
el-autocomplete标签的下拉显示问题
<el-autocomplete
v-model="searchName"
:fetch-suggestions="querySearch"
placeholder="输入房屋名进行搜索..."
prefix-icon="el-icon-search"
@select="handleSelect">
</el-autocomplete>
这里主要是:fetch-suggestions属性
官方的解释是:
但是做的过程发现,从后台获取到的数组中并不能被获取到,就导致以下这种情况:
同样,遇到问题先阅读官方文档:
再看了看自己的从后台传过来的数组:
可以发现一个问题官方的数组每一个数据都有一个value字段!找到函数:
createSearchFilter(queryString) {
return (searchName) => {
return (searchName.value
.toLowerCase()
.indexOf(queryString.toLowerCase())
!== -1);
};
},
一开始我以为自己的逻辑是对的,即只要把searchName.value换成我自己的house_name字段,即可解决问题,结果如下:
很明显我的想法是错的,经过一番斟酌,还是选择了把自己后台传过来的数据处理一下,通过for循环来组成一个心得 {value:‘输入建议’} 这种格式的数组。操作如下:
data() {
return {
houseList: [],
selectName: [],
searchName: '',
timeout: null
}
},
querySearch(queryString, cb) {
const _this = this;
this.axios.get('后端接口地址')
.then(function (resp) {
// console.log(resp.data);
for(let item of resp.data) {
if (JSON.stringify(_this.selectName).indexOf(
//判断值是否已存在与数组
JSON.stringify(item.house_name)
) === -1 )
_this.selectName.push({"value": item.house_name});
};
var selectName = _this.selectName;
// console.log(selectName);
var results = queryString
?selectName.filter(_this.createSearchFilter(queryString))
: selectName;
// 调用 callback 返回建议列表的数据
clearTimeout(_this.timeout);
_this.timeout = setTimeout(()=>{
cb(results);
},1000*Math.random());
})
},
这里注意存值问题,我的for循环是在请求接口的内部写的,所以如果不在for里面添加判断语句:
if (JSON.stringify(_this.selectName).indexOf( //判断值是否已存在与数组
JSON.stringify(item.house_name)
) === -1 )
在重复点击input框的情况下会出现以下重复请求接口导致的数组值叠加问题:
正确结果如下:
结果证明: 从后台获取的数组中每一个对象必须要有一个value字段,也就是说el-autocomplete标签默认识别的是value字段,然后才显示在下拉列中。
但是我深究到底,简而言之就是我不信他只会识别value字段。
通过反复阅读官方文档,发现了一个属性,就是一看就觉得它可以改变el-autocomplete标签默认识别的字段,如下:
上面写着默认值是value,所以我要去template部分设置它,把默认值换成我想要的值:
<el-autocomplete
v-model="searchName"
:fetch-suggestions="querySearch"
placeholder="输入房屋名进行搜索..."
prefix-icon="el-icon-search"
value-key="house_name"
@select="handleSelect">
</el-autocomplete>
再去script方法那换成我理想的样子:
data() {
return {
houseList: [],
此处删除了selectName[]数组
searchName: '',
timeout: null
}
},
querySearch(queryString, cb) {
//queryString为输入的值
//cb即官方文档的callback为回调函数,将处理好的数据推回
const _this = this;
this.axios.get('后端接口地址')
.then(function (resp) {
// console.log(resp.data);
此处删除了for循环遍历获取数组值
var selectName = resp.data;
var results = queryString ? selectName.filter(_this.createSearchFilter(queryString)) : selectName;
// 调用 callback 返回建议列表的数据
clearTimeout(_this.timeout);
_this.timeout = setTimeout(()=>{
cb(results);
},1000*Math.random());
})
},
createSearchFilter(queryString) {
return (searchName) => {
return (searchName.house_name
.toLowerCase()
.indexOf(queryString.toLowerCase())
!== -1);
};
},
返回结果正确
结果证明: 当我使用value-key改变识别的字段之后,完全不用那么麻烦的去重新定义、获取一个数据,后台传过来的数组数据是可以直接用的
el-autocomplete标签下拉选择后页面显示问题
这里的前提是你可以正常查看数据
上面我们已经在el-autocomplete标签加上了@select=“handleSelect”。
handleSelect(item)中的item已经是我们想搜索的东西了,只需要在里面
this.houseList.length = 0;然后再通过$set设置我们的houseList为item即可重置数组。
思路是正确的,但是结果不对,如果我们有两个或以上的value值相同的话,返回的只会是你选择的那个数据:
正确的做法是后端提供一个findBy接口,并在我们的handleSelect方法中调用,即可返回多条数据。
直接上script的handleSelect方法代码:
handleSelect(item) {
// console.log(item);
const _this = this;
this.axios.get('后端接口地址'+item.house_name).then(function (resp) {
// console.log(resp);
_this.houseList = resp.data;
})
}
结果如下,不管你在下拉框选择的是哪一个选项,只要是符合该value的都可以返回出来数据:
结果证明: 通过下拉框选择返回的item只是一个数据,如果需要返回多条数据,需要从后端调用接口实现,当然这里页可以完善以下,把下拉框中重复的内容去掉,不难操作,这里就不详细说了哈
原创不易,如果这篇文章对你有所帮助,请点赞评论支持一下。