• 【Vue.js】基于vue的实时搜索,在结果中高亮显示关键词


    一、搜素效果如下:

    二、核心

      1)利用oninput属性来触发搜素功能

      2)利用RegExp来对字符串来全局匹配关键字,利用replace方法来对匹配的关键字进行嵌入高亮的<span class="gaoliang">标签,最后利用v-html来嵌入html标签来达到关键字高亮显示

      3)利用axios.CancelToken来终止上一次的异步请求,防止旧关键字查询覆盖新输入的关键字查询结果。

    三、代码

      1)HTML  搜索框部分绑定input事件(搜索框独立出来,作为一个基础组件(叫SearchToolbar.vue),嵌入到KnowledgeSearch.vue中)

    <input type="text" class="input-search" placeholder="请输入搜索内容" v-model.trim="searchKey" @input="searchEvent" ref="searchInput" autocomplete="off" autocapitalize="off" autocorrect="off"/>

      2)因为input绑定了输入监听事件@input,每一次输入值的改变,都会触发方法searchEvent(),尤其是在输入搜索关键字的时候,这种情况必然发生发送多次http异步请求,这样频繁地请求会导致流量损耗与性能下降。

    如何解决?

      我们利用setTimeout与clearTimeout元素,控制输入间隔为500ms,如果超过500s还没输入任何东西,就会向后端发送http异步请求。例如在搜索框种输入1,然后500ms过去之后,就会发送异步请求,如果在输入1之后的500ms输入值,例如我在499ms输入了值‘2’,那么上一次关键字为1的异步请求就会取消,进而进行关键字为‘12’的异步请求,并等待500ms。代码如下:

    searchEvent() {
          this.clearTimer();
          if (this.searchKey && this.searchKey.length > 0) {
            //获取当前延时函数的ID,便于后面clearTimeout清除该ID对应的延迟函数
            this.timer = setTimeout(() => {
              this.$emit('searchHandler', this.searchKey);
            }, 500);
          } else {
            this.$emit('searchHandler', this.searchKey);
          }
    },
    
    clearTimer() {
          if (this.timer) {
            clearTimeout(this.timer);
          }
    }    
    

      注意,你仔细想想,这里还存在一个漏洞。根据关键字发送异步http请求,假如在网络环境并不太好的情况下,异步请求可能经过2秒才返回关键字为‘成’的数据给我。然而,我在输入完关键字‘成’,超过500ms之后在输入‘龙’,那么之前的‘成’关键字的http异步请求已经发送给了服务器(要经过2s才返回数据给我。),而关键字为‘成龙’的http异步请求也发送过去了,它的响应时间是1s就返回数据。那么经过2s之后,得到的将会是关键字为‘成’的数据。因为最新的‘成龙’数据(1s)已经被‘成’数据(2s)所覆盖了。

      3)利用axios.CancelToken来终止上一次的异步请求,防止旧关键字查询覆盖新输入的关键字查询结果。

    import httpService from '@/services/HttpService';
    <script>
    export default{
    	data(){
    		return{
    			$http: null,
    			CancelToken: null,
    			cancel: null,
    		}
    	},
    	methods{
    		queryDataListByKey() {
    			if (this.searchKey.length === 0) {
    				this.loadedData = false;
    				this.dataList = [];
    				return;
    			}
    
    			let params = {
    				'pageNo': this.pageNo,
    				'pageSize': this.pageSize,
    				'keyWord': this.searchKey
    			};
    			this.loading(true);
                  // this.cancel === null,意味着第一次请求 if (this.cancel) {
                       // 取消上一次的异步请求 this.cancel('canceled by user'); } this.$http.get('rule/findRuleListByKeyWord', {
                       // 每一次请求关键字资源的http异步请求,都要新建一个异步取消操作实例,并赋值给this.cancel cancelToken: new this.CancelToken((c) => { this.cancel = c; }), 'params': params }).then((res) => { this.loading(false); this.loadedData = true; this.processDataList(res); }, (error) => { this.loading(false); this.loadedData = true; this.loadMoreConfig.loading = true; if (error !== null) { this.$vux.toast.show({ text: '数据加载失败', type: 'text' }); } }); }, } } </script>

      4)v-htmlReg为搜索结果的关键字高亮显示

      这一步是在展示数据的组件上做的。

        4.1)HTML结果数据展示部分

    <div class="title-info" v-html="ruleTitle"></div>

        4.2)js部分

    import httpService from '@/services/HttpService';
    <script>
    export default{
    	props: {
    		// 每一条带关键字的结果对象,父组件传过来的
    		item: {},
    	},
    	computed: {
    		ruleTitle() {
    		  let titleString = this.item.name;
    		  if (!titleString) {
    			return '';
    		  }
    		  if (this.searchValue && this.searchValue.length > 0) {
    			// 匹配关键字正则
    			let replaceReg = new RegExp(this.searchValue, 'g');
    			// 高亮替换v-html值
    			let replaceString = '<span class="search-text">' + this.searchValue + '</span>';
    			// 开始替换
    			titleString = titleString.replace(replaceReg, replaceString);
    		  }
    		  return titleString;
    		}
    	},
    }
    </script>
    

      

  • 相关阅读:
    HDU 4685
    HDU 2519 新生晚会(组合问题)
    HDU 1241 Oil Deposits(递归,搜索)
    数据结构之线性表
    coocs项目的创建
    cocos开发环境搭建
    数据结构之算法时间复杂度
    c++ auto类型说明符
    HDU 6170 Two strings(DP)
    HDU 6138 Fleet of the Eternal Throne(AC自动机)
  • 原文地址:https://www.cnblogs.com/pengshengguang/p/8059190.html
Copyright © 2020-2023  润新知