ITPub博客

首页 > 应用开发 > IT综合 > 教你如何实现直播源代码的搜索功能

教你如何实现直播源代码的搜索功能

IT综合 作者:云豹科技晓彤 时间:2021-08-30 16:58:14 0 删除 编辑

一、需求描述
直播源代码实现一个搜索框:
1、输入关键字,按键抬起后可以实现查询功能;
2、下拉列表展示搜索结果,搜索结果中关键字要用特殊颜色突出显示,默认选中搜索结果的第一项;
3、可以按上下键切换选中项,按回车输出选中项;
4、单击组件之外的地方可以收起下拉列表;

二、分析
直播源代码用到的插件 pinyin-match:
支持拼音全拼、简拼和汉字模糊匹配。
调用match方法,匹配成功返回数组([匹配到第一个字符的下标,匹配到最后一个字符的下标]),失败返回false。

三、代码实现

<template>   <div @click.stop>     <div :class="{'is-focus':isFocus}">       <!-- 搜索输入框 -->       <input type="text"             autocomplete="off"             autocorrect="off"             autocapitalize="off"             autofocus             v-model="value"             ref='searchInput'             spellcheck="false"             placeholder="搜索..."             @click="changeInput"             @keyup="clickSearch"             @keydown.down.prevent="navigateOptions('next')"             @keydown.up.prevent="navigateOptions('prev')">       <!-- 搜索放大镜图标 -->       <div>         <i v-show="value" @click="clearSearchValue"></i>             <i v-show="!value" @click="clickSearch"></i>       </div>           </div>     <!-- 搜索下拉列表 -->     <div>       <div ref="ul">         <ul v-for="item in result">                       <li :class="{'is-selected': item.isSelected}" @click="clickResultItem(item)">             <img src="../../images/avatar.png">             <div>               <span>{{item.keyword[0]}}<span>{{item.keyword[1]}}</span>{{item.keyword[2]}}</span>                                     </div>           </li>         </ul>         <!-- 查询结果为空时候 -->         <div v-if="value && result.length == 0">            没有结果          </div>                </div>     </div>   </div> </template> <script> const PinyinMatch = require('pinyin-match'); export default {   name: 'SearchInput',   data () {     return {       isFocus: false,//搜索框是否获取了焦点       value: '',//输入的搜索关键字       result : [],//全部搜索结果       curIndex: 0,//选中的搜索结果的下标       selectItem: {},//选中的搜索结果       userList: [         {name:'安其拉',id:'a1'},         {name:'安琪',id:'a2'},         {name:'陈仙仙', id:'c1' },         {name:'成小龙', id:'c2' },         {name:'程野', id:'c3' },         {name:'丁小明', id:'d1' },         {name:'丁小龙', id:'d2' },         {name:'丁小野', id:'d3' },         {name:'冯小明', id:'f1' },         {name:'冯小龙', id:'f2' },         {name:'冯小野', id:'f3' },         {name:'高小明', id:'g1' },         {name:'高小龙', id:'g2' },         {name:'高小野', id:'g3' },         {name:'高小阳', id:'g4' },         {name:'郭小名', id:'g5' },         {name:'黄小明', id:'h1' },         {name:'黄小龙', id:'h2' },         {name:'黄小野', id:'h3' },         {name:'郝小阳', id:'h4' },         {name:'郝小名', id:'h5' },         {name:'李小明',id:'l1'},         {name:'李小龙',id:'l2'},         {name:'李小野',id:'l3'},         {name:'李小阳',id:'l4'},         {name:'李小一',id:'l5'},         {name:'李小二',id:'l6'},         {name:'李小三',id:'l7'},         {name:'李小四',id:'l8'},         {name:'李小五',id:'l9'},       ]      }   },   mounted () {        let that = this;        document.body.addEventListener('click', () => {//单击组件之外时收起下拉列表       that.isFocus = false;       that.value = "";     }, false);   },   methods: {     changeInput() {//单击搜索框时获取焦点       this.isFocus = true;       },     clearSearchValue () {//清空输入的查询条件       if (this.value) {         this.value = "";//搜索关键字         this.result = [];//全部搜索结果         this.curIndex = 0;//选中的搜索结果的下标         this.selectItem = {};//选中的搜索结果         this.$refs.searchInput.focus();//输入查询条件清空后获取焦点       }     },     clickSearch () {//查询       if (event.code == "ArrowDown" || event.code == "ArrowUp") {//上下键         return;       }              if (event.code == "Enter" && this.selectItem) {         this.clickResultItem(this.selectItem);//有搜索结果时按下enter直接选中第一项         return;       }       this.result = [];//全部搜索结果       this.curIndex = 0;//选中的搜索结果的下标       this.selectItem = {};//选中的搜索结果       if (this.value.trim()) {                                          for (let i = 0; i < this.userList.length; i++) {//根据所有人员名字匹配           let name = this.userList[i].name;           let search = PinyinMatch.match(name, this.value);                     if (search && search.length > 0) {                            this.userList[i].keyword = this.getKeyWord(name, search);             this.userList[i].isSelected = false;                         this.result.push(this.userList[i]);                    }         }         if (this.result && this.result[0]) {           this.result[0].isSelected = true;           this.curIndex = 0;//选中的搜索结果的下标           this.selectItem = this.result[0];//选中的搜索结果         }              } else {         this.$refs.searchInput.focus();//没有输入查询条件焦点不应该失去       }     },     getKeyWord (name, search) {//关键字       let keyword = [];       keyword[0] = name.substring(0, search[0]);       if (search[0] == search[1]) {         keyword[1] = name.charAt(search[0]);//匹配到的作为关键字         keyword[2] = name.substring(search[0] + 1);       } else {         keyword[1] = name.substring(search[0], search[1] + 1);//匹配到的作为关键字         keyword[2] = name.substring(search[1] + 1);       }       return keyword;     },                  clickResultItem (data) {//单击下拉列表中的选项           alert('您选择了' + data.name);     },     navigateOptions (direction) { //搜索结果上下键选择       let resultLength = this.result.length;       if (resultLength == 0 || resultLength == 1 ) {         return;       }       let lastIndex = this.curIndex;       if (direction === 'next') {//向下               this.curIndex++;            if (this.curIndex === resultLength) {           this.curIndex = 0;         }              }       if (direction === 'prev') {//向上         this.curIndex--;         if (this.curIndex < 0) {                   this.curIndex = resultLength - 1;         }       }       if (lastIndex < resultLength) {                 this.result[lastIndex].isSelected = false;       }       if (-1 < this.curIndex < resultLength) {         this.selectItem = this.result[this.curIndex];         this.selectItem.isSelected = true;             // this.result[this.curIndex].isSelected = true;          this.$set(this.result,this.curIndex,this.selectItem)            }       this.resetScrollTop();     },     resetScrollTop () { //设置滚动条的位置       let maxShowCount = this.$refs.ul.clientHeight / 50;       let diff = this.curIndex - maxShowCount;              diff += 4;             this.$refs.ul.scrollTop = diff * (50) + 60;     },   } } </script> <style src="./index.scss"></style>

index.scss

.search-wrapper {   background-color: rgb(235, 148, 148);   height: 580px;   width:325px;    overflow: hidden;   border-radius: 3px;   font-family: 'Microsoft YaHei';   box-sizing: border-box;   padding: 10px;   .search-input{     position: relative;     input {       width: 100%;       height: 35px;       box-sizing: border-box;       border: 0;       border-radius: 3px;       margin: 0;       padding: 0px 40px 0px 10px;       outline: 0;       font-size: 14px;       color: #E5EAEE;       // background-color: #209df7;       background-color: #fff;     }     input::-webkit-input-placeholder {       color: #E5EAEE;     }     .search-icons {       position: absolute;       top: 7px;       right: 10px;       color: #209df7;       font-size: 17px;     }   }   .is-focus {     overflow: visible !important;     input {       color: #222 !important;       // border: 1px solid #fff !important;       // background-color: #fff !important;       box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2), 0 1px 15px hsla(0, 0%, 100%, .3) !important;     }     .search-icons {       .el-icon-close{         color: #111;         background-color: #d8d8d8;         border-radius: 50%;         padding: 2px;         box-sizing: border-box;         font-size: 15px;         cursor: pointer;       }       .el-icon-close:hover{         color: #fff;         background-color: #209df7;       }     }   }   .search-list{     height: 480px;     margin-top: 8px;     border: 0 none;         border-radius: 3px;     box-shadow: 0 0 6px rgba(0, 0, 0, .15);        background-color: #fff;         .search-result {       height: 100%;       overflow-x: hidden;       overflow-y: auto;       ul, li{         margin: 0px;         padding: 0px;       }       li{         list-style-type: none;       }       .select-li {         cursor: pointer;         padding: 8px 10px;         overflow: hidden;         border-bottom: 1px solid #ebebeb;         .user-avatar {           border-radius: 50%;           float: left;           width: 40px;           height: 40px;           background-size: cover;         }         .user-name {           width: 200px;           float: left;           margin-left: 15px;           line-height: 40px;           .keyword {             color: #008cee;           }         }        }       .select-li:hover{         background-color: #e5f0fa;       }       .is-selected {         background-color: rgba(140, 197, 255, 0.46)       }     }     .result-null {       margin-top: 100px;       text-align: center;       font-size: 20px;     }   } } ::-webkit-scrollbar {   width: 6px;   height: 6px; } /*滑动轨道*/      ::-webkit-scrollbar-track-piece {   background-color: transparent;   -webkit-border-radius: 6px; }   // 下面是滑块 /*竖向滚动条*/       ::-webkit-scrollbar-thumb:vertical {   height: 5px;   background-color: rgb(161, 161, 161);   -webkit-border-radius: 6px; } /*横向滚动条*/           ::-webkit-scrollbar-thumb:horizontal {   width: 5px;   background-color: rgb(143, 144, 145);   -webkit-border-radius: 6px; }

三、效果

在这里插入图片描述

以上直播源代码就实现了一个简单的搜索框。

下面对直播源代码的搜索过程进行简单的优化:

在data中添加  timer:null
将搜索过程放入  setTimeout 函数中,按键抬起半秒后再去进行搜索。

    clickSearch () {//查询       if (event.code == "ArrowDown" || event.code == "ArrowUp") {//上下键         return;       }              if (event.code == "Enter" && this.selectItem) {         this.clickResultItem(this.selectItem);//有搜索结果时按下enter直接选中第一项         return;       }       this.result = [];//全部搜索结果       this.curIndex = 0;//选中的搜索结果的下标       this.selectItem = {};//选中的搜索结果       if (this.value.trim()) {              clearTimeout(this.timer);         this.timer = setTimeout(function () {         for (let i = 0; i < this.userList.length; i++) {//根据所有人员名字匹配           let name = this.userList[i].name;           let search = PinyinMatch.match(name, this.value);                     if (search && search.length > 0) {                            this.userList[i].keyword = this.getKeyWord(name, search);             this.userList[i].isSelected = false;                         this.result.push(this.userList[i]);                    }         }         if (this.result && this.result[0]) {           this.result[0].isSelected = true;           this.curIndex = 0;//选中的搜索结果的下标           this.selectItem = this.result[0];//选中的搜索结果         }                 }, 500)                                               } else {         this.$refs.searchInput.focus();//没有输入查询条件焦点不应该失去       }     },

本文由云豹科技转发自五花漏博客,如有侵权请联系作者删除


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70002045/viewspace-2789504/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
音视频软件开发相关知识科普账号

注册时间:2021-06-11

  • 博文量
    163
  • 访问量
    60341