• VUE2开发实战——搜索功能


    总结

    之所以放前面是因为正文部分写的比较乱。

    做这个功能让我想起刚毕业的一次面试问题,问题是“如何实现搜索功能”,当时的回答大概是根据关键字遍历数据集然后提取匹配到记录等等,反正现在想来回答是很水的。说这个的重点不是面试,而是想说说自己心态的改变。

    毕业找工作:工作经验?不存在的。道理我都懂,给我点时间我什么都能做。

    现在:工作经验?存在的。没实际的写过一些东西,不踩过一些坑,怎么可能成长起来。比如开发过这个搜索功能,有过权重的计算方式,知道自己还可以改进的地方,能够更快更好的开发这个功能,哪怕需求有变动,掌握了原理的东西,就可以明月照大江。

    这篇文章本来7月份就该写了的,但是一直没静下心来。这两个月工作任务倒是不重,主要空余时间放在巩固基础上了。

    前端的东西确实比较多,H5、CSS3,ES6新增的东西到现在还没都用一遍,这些也是现在前端的基础吧,虽然有些用的少+浏览器兼容问题,但是知道总比不知道好很多。还有各种的框架、webApp要走的路还很长....

    目前在干的事: node.js、webApp、vue.js、

    nodejs从爬虫上手的,目前爬了教学式的豆瓣电影、BOSS直聘的招聘信息、xiciIP的代理IP,也放在自己的github上面了,后面会写关于爬虫的东西。

    另外...自己的写作水平还需要提高啊,有些东西总感觉没说清晰,有没看懂的部分可以留下评论,我会认真回复的。

    正文

    先看UI的设计图。

     

    当然还有后续的功能,但是针对搜索框开发,所以就不谈后续了。

    首先说说主要的技术点和经验,因为开发的时候先做的这个东西

    1.关于原生select

    由于原生select中,option只能修改部分样式,不能完全达到图中的效果,故果断放弃,采用div+ul和绝对定位对其进行模拟。

    2.历史搜索记录

    要求:1.保存用户搜索记录;2.点击空白状态的文本框时显示记录;3.最多8条,排序以最近搜索为先;4.提供清除。

    思路:

      1.保存记录--每次搜索一个正确数据之后,由于结构固定且有排序操作,采用数组searchHis存取,将该数组Stringify后存入localStorage.

      2.点击显示--文本框绑定事件,在keywords为空的时候取出searchHis,再显示到页面中.

      3.最多8条 有排序--属于先进先出,典型的队列操作,用数组的unshift实现头部插入,然后判断length>8?length=8:不变,length置8即把尾部多余的删去.

      4.提供清除--目前是做的清除所有,也就是localStorage.removeItem删除。若是删除指定某记录,则先取出searchHis,然后删除该条后重新放入localStorage

    再来说踩过的坑,算是自己不够仔细,

    bug:由于localStorage是针对网站x存储的,故同一浏览器登录x的所有用户都可以取出该记录,相当于一台电脑上同一浏览器登录的用户共享一个记录...

    解决办法:在命名时候针对当前登录用户做标识。

    3.搜索匹配的权重计算+匹配字符添加样式

    这个功能打算单独提出来再仔细说,先放权重计算的思路。


    此搜索功能可根据输入的汉字、拼音、代码(英文+数字)、拼音首字母 对机场a[ ]、航司b[ ]进行查询,相当于输入英文要匹配3组数组,故中文可以直接匹配,所以权重计算针对英文。

    在结果集优先显示机场,然后航司,所以先匹配机场的数据源push到结果集,再匹配航司,可以解决优先显示的问题。

    匹配规则:拼音首字母>代码>拼音,

    一开始设计匹配方法的时候,直接匹配到了就提取,没有加入权重计算,故每次匹配会被数据源a[],b[]本身的数组序列影响结果,

    用机场数据举例:

    a[0]==={
    qp: 'chengdushuangliu',
    zn: '成都双流',
    code: 'CTU',
    sp: 'CDSL'
    }
    a[99]==={
    qp: 'hangzhouxiaoshan',
    zn: '杭州萧山',
    code: 'HGH',
    sp: 'HZXS'
    }

    这时候输入H,则搜索结果中会这样显示:

    chengdushuangliu...

    hangzhouxiaoshan...

    因为在遍历的时候先从a[0]中找到了cheng,就push到结果集中进行a[1]匹配,这样明显与优先匹配拼音首字母要求不符合,先看看原来的代码

    if(vval.py.toLowerCase().indexOf(word)> -1 ){//拼音
      return r.push(vval);

    }
    if(vval.code.toLowerCase().indexOf(word)> -1 ){//代码
      return r.push(vval);

    }
    if(vval.airportName.indexOf(word)> -1 ){//中文
      return r.push(vval);

    }
    if(vval.pinyin.toLowerCase().indexOf(word)> -1 ){//
      return r.push(vval);
    }

    解决思路:在外层添加一个counter,用于记录匹配次数,然后根据匹配次数对数据集进行排序。在循环外层声明一个二维数组nr[ [ ], [ ], [ ], [ ], [ ] ],用于存放不同权重的结果。

    新代码:

        let counter = 4;
        if(vval.py.toLowerCase().indexOf(word)> -1 ){
            counter --;
            nr[counter].push(vval);
        }
        if(vval.code.toLowerCase().indexOf(word)> -1 ){
            counter --;
            nr[counter].push(vval);
        }
        if(vval.airportName.indexOf(word)> -1 ){
            counter --;
            nr[counter].push(vval);
        }
        if(vval.pinyin.toLowerCase().indexOf(word)> -1 ){        
            counter --;
            if(vval.pinyin.toLowerCase().indexOf(word) == 0){   //如果匹配到为拼音首字母则优先显示
                counter --;
            }
            nr[counter].push(vval);
        }

    最后把nr[0-4]合并,就可以把权重高的放在前面了,这也是代表权重的counter为什么是--的原因。

     

  • 相关阅读:
    ResponsiveSlides.js最轻量级的幻灯片插件
    jQuery.extend 函数详解
    HQL查询语言的使用介绍
    使用Hibernate命名查询
    Jquery.KinSlideshow图片轮播插件
    关于文件下载自己忽略的文件中文命名。。。
    DB2中的ROW_NUMBER() OVER()函数用法
    css ul li 水平布局问题
    彻底弄懂css中单位px和em,rem的区别 转的自己看
    taglib 自定义标签
  • 原文地址:https://www.cnblogs.com/lonhon/p/github_LonHon.html
Copyright © 2020-2023  润新知