在现在的互联网世界里,自动完成的搜索功能是一个很常见的功能。比如百度搜狗360搜索 ...

功能描述一下大概是这个样子的:有一个搜索框,用户在里面输入要查询的条件,系统会“智能”判断用户输完了,然后自动根据条件去搜索相关的数据返回给用户。

网上这个自动完成的插件很多,实现自动完成功能也不复杂,特别是像vue、angularjs、react这类可以实现双向绑定的库出现以后,实现就更方便了。本文不讲自动完成功能的实现,而是介绍自动完成功能后续数据的请求该如何考虑,主要要处理下面两个问题。

问题1:自动完成搜索触发频率如何控制?

问什么要控制自动完成搜索的触发频率呢?大家都知道,自动完成触发基本上都是键盘响应事件,在文本框中输入一个文本就触发一次,这个太频繁了。比如我要输入的搜索条件是abcdefg,输入a触发一次,接着输入b再触发一次,接着输入c又触发一次...,等到我把这几个字母全部输完就触发了7次,假设请求逻辑没有限制的话,这就会发生7次数据请求,而实际上只有第7次的结果才是我想要的,其它6次数据请求完全是浪费资源。在用户需求上来说,用户真正希望的是搜索框能自动识别到用户的abcdefg这一串字符全部输入完了,然后再触发请求数据。对于一些变态的输入,比如按住某一个建不放,还不知道要触发多少次。

所以控制自动完成搜索的触发频率还是很有必要的。当然,搜索框能完全智能的知道用户所想然后去触发,在目前来说还是做不到的。

我这里使用控制空闲时间的间隔的方式来限制自动完成搜索的触发频率。使用lodash库中的debounce方法。

问题2:数据还在请求中时再次触发请求,上次的请求如何取消?

为什么要取消上次的请求你?举个例了,我输入了查询条件"xxx",数据请求发送了,我们暂且把它称为请求1。因为某些原因(比如说网络不好,这个条件的数据量大等等),请求1响应很慢,我们在请求1还没用拿到数据的时候又输入查询条件"yyy"发送了请求2,没想到这个请求2数据响应特别快,一下子就得到了数据data,我们准备把data展示出来,这时候请求1的数据回来了,data会被覆盖掉,也就是说这时候我们用"yyy"的条件查询得到了"xxx"条件的查询结果。这个结果其实是超出用户期望的。所以在发送新的请求之前,如果上次的请求还没有结束,我们就需要取消掉它。

我这里使用axios的CancelToken来取消请求。

下面列出主要代码:

hello.vue:

<template>
<div class="hello">
<!--使用mint-ui的搜索组件-->
<mt-search v-model="searchKey" @input="search"></mt-search>
<span>{{result}}</span>
</div>
</template> <script>
import _ from 'lodash'; //引入lodash
import axios from 'axios' //引入axios //请求canceltoken列表
let sources = []; export default {
name: 'hello',
data () {
return {
searchKey: '', //查询条件
result: '' //查询结果
}
},
methods: {
//使用_.debounce控制搜索的触发频率
//准备搜索
search: _.debounce(
function () {
let that = this;
//删除已经结束的请求
_.remove(sources, function (n) {
return n.source === null;
});
//取消还未结束的请求
sources.forEach(function (item) {
if (item !== null && item.source !== null && item.status === 1) {
item.status = 0;
item.source.cancel('取消上一个')
}
}); //创建新的请求cancelToken,并设置状态请求中
var sc = {
source: axios.CancelToken.source(),
status: 1 //状态1:请求中,0:取消中
};
//这个对象加入数组中
sources.push(sc);
      //开始搜索数据,yourhttp替换成你自己的请求路径
axios.get('yourhttp', {
cancelToken: sc.source.token
}).then(function (res) {
//请求成功
sc.source = null; //置空请求canceltoken //TODO这里处理搜索结果
console.log(res.data);
that.result = res.data; }).catch(function (thrown) {
//请求失败
sc.source = null; //置空请求canceltoken //下面的逻辑其实测试用
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
//handle error
} });
},
500 //空闲时间间隔设置500ms
)
}
}
</script> <style scoped>
.mint-search {
height: auto;
}
</style>

我的测试效果图:

vue自动完成搜索功能的数据请求处理的更多相关文章

  1. CI 结合 vue.js 的搜索功能模块

    CI 结合 vue.js 的搜索功能模块 最近在有优化公司后台的某个模块的搜索功能优化 原先的是这个样子的,很是单调: 老大给我找个图希望我能弄成这样子: 经过不断修改,最后成了这样子 是不是比以前好 ...

  2. Python模拟百度自动输入搜索功能

    # 访问百度,模拟自动输入搜索 # 代码中引入selenium版本为:3.4.3 # 通过Chrom浏览器访问发起请求 # Chrom版本:59 ,chromdriver:2.3 # 需要对应版本的C ...

  3. 使用vue实现自定义搜索功能

    实现效果如:http://www.ligerui.com/demos/filter/filter.htm 代码: <%@ Page Language="C#" AutoEve ...

  4. (GoRails)在导航栏增加自动的搜索功能(jquery插件:easyautocomplete)(gem 'ransack' 搜索对象4000✨)

    Global Autocomplete Search 需要用到一个JQuery插件和一个搜索对象的gem EasyAutocomplete jQuery插件: https://github.com/p ...

  5. 用vue实现百度搜索功能

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. vue中实现中,自动补全功能

    知识点:利用vue的基本语法实现,自动补全功能 参考博客:https://www.jb51.net/article/136282.htm 效果:在文本框中,输入相关名称,调用后台接口,将数据填充到下拉 ...

  7. StringBoot整合ELK实现日志收集和搜索自动补全功能(详细图文教程)

    @ 目录 StringBoot整合ELK实现日志收集和搜索自动补全功能(详细图文教程) 一.下载ELK的安装包上传并解压 1.Elasticsearch下载 2.Logstash下载 3.Kibana ...

  8. ThinkPHP之中getlist方法实现数据搜索功能

    自己在ThinkPHP之中的model之中书写getlist方法,其实所谓的搜索功能无非就是数据库查询之中用到的like  %string%,或者其他的 字段名=特定值,这些sql语句拼接在and语句 ...

  9. 第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能

    第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—用Django实现搜索的自动补全功能 elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.e ...

随机推荐

  1. (转载)CPU、内存、硬盘、指令以及他们之间的关系

    CPU.内存.硬盘.指令以及他们之间的关系 最近读完<程序是怎样跑起来的>以及<深入理解计算机系统>的3.6.9章节后对计算机的组成有了更深入细致的了解,现总结一下对CPU.内 ...

  2. 字体反爬--css+svg反爬

    这个验证码很恶心,手速非常快才能通过.. 地址:http://www.dianping.com/shop/9964442 检查一下看到好多字没有了,替代的是<x class="xxx& ...

  3. 如何在优雅地Spring 中实现消息的发送和消费

    本文将对rocktmq-spring-boot的设计实现做一个简单的介绍,读者可以通过本文了解将RocketMQ Client端集成为spring-boot-starter框架的开发细节,然后通过一个 ...

  4. .NET线程池最大线程数的限制-记一次IIS并发瓶颈

    .NET ThreadPool 最大线程数的限制 IIS并发瓶颈,有几个地方,IIS线程池的最大队列数,工作进程数,最大并发数.这些这里就不展开.主要是最近因为过度使用Task 导致的线程数占用过多, ...

  5. Python with/as和contextlib上下文管理使用说明

    with/as 使用open打开过文件的对with/as都已经非常熟悉,其实with/as是对try/finally的一种替代方案. 当某个对象支持一种称为"环境管理协议"的协议时 ...

  6. Go基础系列:指定goroutine的执行顺序

    Go channel系列: channel入门 为select设置超时时间 nil channel用法示例 双层channel用法示例 指定goroutine的执行顺序 当关闭一个channel时,会 ...

  7. 翻译:CREATE TRIGGER语句(已提交到MariaDB官方手册)

    本文为mariadb官方手册:CREATE TRIGGER的译文. 原文:https://mariadb.com/kb/en/create-trigger/我提交到MariaDB官方手册的译文:htt ...

  8. Webapi--Webapi 跨域链接

    1]创建 WebAPIWebAPI WebAPI,新建 ,新建 ->项目 ->ASP.NET Web >ASP.NET Web >ASP.NET Web >ASP.NET ...

  9. Serilog记录MongoDB日志报错:requires the binary sub type to be UuidLegacy, not UuidStandard

    Serilog Serilog是.NET开源结构化日志类库 开源地址:https://github.com/serilog 官网:https://serilog.net/ Serilog能做什么: 记 ...

  10. [转]angular 监听窗口滚动

    本文转自:https://blog.csdn.net/ittvibe/article/details/80060801 转自:http://brianflove.com/2016/10/10/angu ...