vue自动完成搜索功能的数据请求处理

在现在的互联网世界里,自动完成的搜索功能是一个很常见的功能。比如百度搜狗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>

我的测试效果图:

时间: 2024-08-28 03:54:48

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

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

知识点:利用vue的基本语法实现,自动补全功能 参考博客:https://www.jb51.net/article/136282.htm 效果:在文本框中,输入相关名称,调用后台接口,将数据填充到下拉div中,然后选择相应的选项,将值赋值到文本框中 (暂时是离开文本框,触发下拉框div,之后会改进demo) 代码: <div style="width: 800px"> <div v-for="(v,i) in contactlist"> &l

js搜索框实现自动搜索功能

做项目的时候,老板让我自己封装一个搜索功能,就类似于百度这种 输入了字符之后,就可以自动搜索数据,而且还会出现一个下拉框供用户选择,我觉得我老板有问题,网上有这么多插件,不仅封装好了,性能也做了优化,什么功能都有,他不用,一定要我用原生js写,写毛线写,我内心吐槽了很久,不过还是要做,为了工资而低头,所以我这个小白就硬着头皮写完了,肯定有很多不足,也没有封装,就是想到哪里写到哪里,给大家当反面教材看看,如果大家看见了,也可以指点指点我,让我进步 由于我是在项目里写的,所以有很多东西和大家的肯定不

四十七 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能

elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html 1.创建搜索自动补全字段suggest 自动补全需要用到一个字段名称为suggest类型为Completion类型的一个字段 所以我们需要用将前面的elasticsearch-dsl操作elasticsearch(搜索引擎)增加sugg

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

第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲-用Django实现搜索的自动补全功能 elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html 创建自动补全字段 自动补全需要用到一个字段名称为suggest类型为Completion类型的一个字段 所以我们需要用

ExtJs4.2应用:使用ExtJs扩展组件searchfield实现数据搜索功能

ExtJs4.2应用:使用ExtJs扩展组件searchfield 实现数据搜索功能 1.引入searchfield组件 在Ext目录下放入ux目录将searchfield组件放入ux目录下的form文件下,如图所示: 2.在对应Js文件中引入searchfield组件 dockedItems: [{ dock: 'top', /**在顶部显示*/ xtype: 'toolbar', /**以工具栏形式展示*/ items: { width: "25%", fieldLabel: 'L

【Android】实现搜索的自动补全功能

[Android]实现搜索的自动补全功能 功能分类:特效 支持平台:Android 运行环境:Eclipse 开发语言:Java 开发工具:Eclipse 源码大小:815.56KB 下载地址:http://www.dwz.cn/x9bUV 源码简介 利用Sqlite模糊查询实现搜索框的自动补全效果(支持字母+汉字补全)欢迎各位小伙伴提供更好的实现思路 运行截图

vue添加,删除,搜索功能

<!--new 的 vue 实例会控制这个元素中的所有内容,也是MVVM中的 V --> <div id="app"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">添加效果</h3> </div> <div cl

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

自己在ThinkPHP之中的model之中书写getlist方法,其实所谓的搜索功能无非就是数据库查询之中用到的like  %string%,或者其他的 字段名=特定值,这些sql语句拼接在and语句之中: HTML之中: 1 <form action="" method="get"> 2 <table class="account_table" width="100%" cellpadding="

使用Redis实现中英文自动补全功能详解

1.Redis自动补全功能介绍: ? Redis可以帮我们实现很多种功能,今天这里着重介绍的是Redis的自动补全功能的实现.我们使用有序集合,并score都为0,这样就按元素值的字典序排序.然后我们可以根据排序号的字符,进行添加前缀和后缀的方式,找到我们想要的区间内容.下面介绍一个简单的Zset的排序内容和思路,以便后续的理解: 名称为redis_concat的Zset集合元素如下: 编号 数值 分值 1 a 0 2 ab 0 3 abcd 0 4 abef 0 5 hjk 0 6 dbfgl