那些年,微信小程序仿网易云音乐有关实时搜索功能

广告:宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取~~~

那些年,微信小程序仿网易云音乐有关实时搜索功能

相关学习推荐:微信小程序教程

前言

前段时间我的小伙伴已经将网易云音乐小程序的音乐播放功能详细的介绍出来了,作为前端小白学习了一段时间,最近也比较忙,没有及时将实时搜索这块内容及时写出来跟大家分享(其实代码和功能之前就写的差不多了),那么今天就给大家讲一讲个人在里面的一些细节和优化吧。

搜索功能很常见,很多地方都能用到,希望能够给大家分享到有用的东西,同时,有不足的地方,也希望各位大佬指出,给出一些修改的意见,小白在此感谢了!

实时搜索功能里面我们也需要用到API接口,从input框输入值到搜索建议,再到搜索结果,最后到跳转歌曲播放,不再只是接那么简单,传值很关键,同时不同功能下不同容器框的隐藏与显示,还有一些搜索当中涉及的细节内容和优化。让我们一起来看看吧!

界面预览
界面分析

头部搜索栏中:左边返回箭头,中间输入框,右边歌手排行榜页面跳转;至于清除按钮呢我们隐藏了起来,只有在输入输入值之后才会出现。

往下时历史记录,像每个搜搜的记录值这里都是一小块一小块等隔距离分布,搜索值有多长,这小块就有多长,这里用到的是display: flex;flex-wrap: wrap;,对这个界面样式感兴趣的小伙伴可以待会看看全部代码。

接下来是热搜榜,这里没有太多讲究,就是发起接口请求数据,把数据埋进去显示出来就行了。

搜索建议会在输入结束后才会出现,并且是很立体的一块覆盖在整个页面上,用box-shadow: 1px 1px 5px #888888达到立体效果,z-index起到覆盖的效果。

搜索结果会在点击搜索建议中的某一条或者点击搜索历史或者热搜才出现,同时界面上其他所有的容器快都会隐藏起来,这里其实就是一个容器框的隐藏与出现的小细节了,待会在功能中我们会详细讲到。这里我们先讲一下组件(容器)如何进行隐藏与显示,以免下面的功能中看到这几项内容蒙圈

几个容器的头部展示

<!-- 点击×可以清空正在输入 --><image class="{{showClean ? 'header_view_hide' : 'clean-pic'}}" src="../../image/search_delete.png" bindtap="clearInput" />复制代码
登录后复制
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码
登录后复制
<!-- 搜索结果 --><view class="{{showSearchResult ? 'header_view_hide' : 'search_result_songs'}}">复制代码
登录后复制
<!-- 搜索历史 --><view class="{{showView?'option':'header_view_hide'}}">复制代码
登录后复制
<!-- 热搜榜 --><view class="{{showView?'option':'header_view_hide'}}">复制代码
登录后复制

解析:这里只放了这几块容器的头部的内容,在data数据源中分别放了showClean,showSongResult,showSearchResult,showView,为true 则这几块容器默认为:(冒号)前面的样式,为false则默认为:(冒号)后面的样式;header_view_hide样式设置为display: none;,即隐藏不显示;所以当在某一个方法中可以去改变showClean,showSongResult,showSearchResult,showViewtrue还是false可以让这几块容器分别为显示或是隐藏。

接口封装

接口封装在上一篇我的小伙伴已经讲的十分清晰了,我们这里不再多去讲解了,同样现在用到的功能也不只是光调接口请求数据那么简单了,我们需要传值给接口,让接口收到值后再给我们返回相应的数据;在搜索界面我们用到的是搜索建议以及搜索结果的接口。热搜榜我们暂时只使用最基础的wx.request直接获取数据

api.js

const API = {    getSearchSuggest: (data) => request(GET, `/search/suggest`, data),  // 搜索建议接口    getSearchResult: (data) => request(GET, `/search`, data),  // 搜索结果接口}复制代码
登录后复制
实时搜索功能:1.数据源分析

一个搜索功能我们设计到的数据会有很多,可以细列一下:输入的值inputValue,在输入时获取;热搜榜数据hots,热搜接口获取;搜索关键词searchKey,本身就是输入框的值,用来传递给搜索建议作为搜索关键词;searchSuggest,搜索建议接口拿到搜索关键词后返回的的数据(搜索建议);搜索结果searchResult,当点击搜索建议中的某一条,该值将填入搜索框,此时搜索关键词searchKey将变为该值又传递给搜索结果接口,并返回数据放入searchResult;最后是搜索历史history,每当进行一次搜索,将原本输入框的值放到history数据源中。关于其他数据源涉及到组件隐藏与展示,即每一块的容器框在何种情况下隐藏,何种情况下显示。

数据源展示

data: {    inputValue: null,//输入框输入的值    history: [], //搜索历史存放数组    searchSuggest: [], //搜索建议    showView: true,//组件的显示与隐藏    showSongResult: true,    searchResult: [],//搜索结果    searchKey: [],    showSearchResult: true,    showClean: true,    hots: [] //热门搜索 }复制代码
登录后复制
2.获取热搜榜

这里我们直接在页面的初始数据中调用接口,直接获取到数据使用

onLoad: function (options) {    wx.request({      url: 'http://neteasecloudmusicapi.zhaoboy.com/search/hot/detail',      header: { "Content-Type": "application/json" },      success: (res) => {  // console.log(res)        this.setData({          hots: res.data.result.hots })      }    })  },复制代码
登录后复制
3.获取input文本

前面已将讲过,搜索建议和结果的接口并没有直接的获取方式,需要我们进行传值,所以首先我们需要获取到输入框的值

input框内容分析

<input focus='true' type="text" class="weui-search-bar__input" placeholder="大家都在搜 " placeholder-style="color:#eaeaea" value='{{inputValue}}' bindinput="getSearchKey" bindblur="routeSearchResPage" bindconfirm="searchOver" />复制代码
登录后复制

小程序中关于input输入框的相关属性大家可以去详细了解一下;placeholder为输入框为空时占位符,即还没输入前输入框显示的内容,placeholder-style可以去设置placeholder的样式;value是输入框的初始内容,即自己在输入框输入的内容,我们在这里直接将输入的内容value直接作为了data数据源中inputValue的内容;bindinput是在键盘输入时触发,即我们一进行打字,就能触发我们的自定义事件getSearchKey,并且会返还相应数据;bindblur在输入框失去焦点时触发,进行搜索功能时,需要在搜索框输值,此时焦点一直在输入框,当点击输入框以外的地方即输入框失去焦点,同时触发routeSearchResPage事件,还会返回相应的数据,在下面功能中会讲到;bindconfirm在点击完成按钮时触发,这里绑定一个searchOver,用来隐藏组件(容器块),再次触发搜索功能,在下面的功能中也会讲到。

获取input文本

getSearchKey: function (e) {    // console.log(e.detail) //打印出输入框的值    if (e.detail.cursor != this.data.cursor) { //实时获取输入框的值      this.setData({        showSongResult: true,        searchKey: e.detail.value })      this.searchSuggest();    }    if (e.detail.value) { // 当input框有值时,才显示清除按钮'x'      this.setData({        showClean: false  // 出现清除按钮 })    }    if(e.detail.cursor === 0){      this.setData({  // 当输入框没有值时,即没有输入时,隐藏搜索建议界面,返回到最开始的状态        showSongResult: false })      return    }  }复制代码
登录后复制

bindinput本身是会返回数据,在代码运行时,可以打印出来先看看; e.detail.value即为输入框的值,将它赋值给searchKey; 查看打印数据e:

解析:

疑惑的小伙伴可以将代码运行,打印出以上设计的几个数据进行分析

①当此时输入框的值和bindinput返回的输入框的值时一样的,就将输入框的值赋给搜索关键词searchKey,此时显示搜索建议栏(showSongResult写在wxml当中,用来控制该容器是否展示,可以看到最后面发的整个界面的wxml中的详情);同时searchSuggest事件(方法)生效。

②当输入框没值时,清除按钮x是不会显示的,只有当输入框有值是才会出现清除按钮x

③当输入框没有值时,隐藏搜索建议栏,其实本身我们最开始进入这个页面时,输入框是没值的,搜索建议栏也是不展示的,为没进行输入就没有数据;但是当我们输入内容后,出现搜索建议,此时我们点击清除按钮,输入框的内容没了,但是搜索建议还停留在之前的状态,所以这里我们优化一下,让showSongResultfalse,即一清空输入框内容,隐藏掉搜索建议栏。另外我们为什么要return呢?这里还有一个bug,当清除输入框内容后,再输入发现已经不再具备搜索功能了,所以需要return回到初始的状态,就能重新进行输入并且搜索。同时当输入框为空时进行搜索功能还会报错,这也是一个bug,所以有了return即使空值搜索也会立马回到初始状态,解决了空值搜索报错的bug

4.搜索框其他功能

清空输入框内容

<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码0
登录后复制

点击清除按钮,就让inputValue值为空,即输入框的内容为空,达到清除文本的效果;在获取输入框文本那里我们也提到了清除按钮,也提到输入框文本清空时,之前的搜索建议栏还会留下,所以这里我们让showSongResultfalse,使得搜索建议栏隐藏。清除文本的同时再隐藏掉清除按钮。

取消搜索返回上页

<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码1
登录后复制

这里用到的小程序自带的返回页面的功能,当给delta值为0即回到上一个页面。(可去文档查看详情)

跳转歌手排行榜

<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码2
登录后复制

在微信官方文档可以查看到navigateTo的功能及其属性,这里不多讲。

5.搜索建议
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码3
登录后复制

解析:开始我们将接口进行了封装,在上一篇讲播放的文章中我的小伙伴已经把接口跟封装讲的很仔细了,这里我们就不在讲这个了,就分析我们的接口。searchKey作为搜索关键词需要传递给接口,在前面的getSearchKey方法中,我们已经讲输入框的内容传给了searchKey作为它的值;所以此时我们拿到有值的searchKey传递给接口,让接口返回相关数据,返回的数据中的res.data.result.allMatch就是从搜索关键词返回的搜索建议里的所有歌名,在将这些数据放到searchSuggest数据源中,这样在wxml埋好的空就能拿到数据,将搜索建议栏显示出。

6.搜索结果搜索建议内的歌曲点击事件
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码4
登录后复制

解析:首先点击事件可以携带额外信息,如 id, dataset, touches;返回参数eventevent本身会有一个currentTarget属性;这里解释一下data-value='{{item.keyword}}=>data就是dataset;item.keyword是搜索建议完成之后返回的数据赋值给searchSuggest里面的某个数据;当一点击搜索建议里面的某一个歌名时,此歌名即为此时的item.keyword,并将该值存入点击事件的参数event内的dataset。大家也可操作一波打印出来看看结果,currentTarget.dataset.value就是我们点击的那个歌曲名字。所以一点击搜索建议中的某个歌名或者搜索历史以及热搜榜单中的某个歌名时,点击事件生效,返回这样该歌曲名称,并将该值给到此时的searchKeyinputValue,此时输入框的值会变成该值,搜索结果的关键词的值也会变成该值;同时this.searchResult()可让此时执行搜索结果功能。showSongResult: false这里还将搜索建议栏给隐藏了。增加showClean: false是为了解决点击后输入框有值但不显示清除按钮的bug查看打印数据e:

返回搜索结果
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码5
登录后复制

解析:上面的歌曲名称点击同时触发了搜索结果的功能,将点击后的新的keywords传递给了搜索结果的接口,接口请求后返回给我们数据,数据中的res.data.result.songs为搜索到的歌曲,此时将它赋值给到searchResult,这样搜索结果栏中会拿到数据,并且showSearchResult: false让搜索结果栏显示出来;这里还做了搜索历史栏和热搜栏的隐藏功能注:搜索结果和搜索建议都需要将搜索关键词传递给接口,不清楚的小伙伴可以去查看接口文档研究一下:https://binaryify.github.io/NeteaseCloudMusicApi/#/

搜索完成后的优化
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码6
登录后复制

解析:前面我们讲到过, searchOver是绑定在input框中的bindconfirm事件,即点击完成按钮时触发。当我们搜索完成之后,界面上还有搜索栏以及搜索结果的显示,此时我们再次点击输入框,可以进行清除文本,同时我们还需要增加一个功能,即在此种情况下,我们还可以进行再次输入并且返回搜索建议以及点击搜索建议中的歌曲时再次执行搜索结果功能。

7.搜索历史input失去焦点
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码7
登录后复制

解析:之前讲过routeSearchResPage事件时放在input框中的,输入框失去焦点时触发,即不在输入框内进行输入,点击输入框以外的内容时触发。当输入完成时会出现搜索建议,此时焦点还在输入框,当我们点击搜索建议中的某一天时,输入框即失去焦点,此时该事件触发。失去焦点函数是在搜索建议事件后发生,此时的搜索关键词为搜索建议的搜索关键词,前面也讲到过,这个搜索关键词就是我们在输入框输入的文本内容,所以将此时的搜索关键词赋值给搜索历史history注:关于搜索历史,我们这里增加了一个判断,即当搜索关键词不为空时,才会拿到搜索关键词给到搜索历史里面,否则,每一次不输入值也去点击输入框以外,会将一个空值传给搜索历史,导致搜索历史中会有空值得显示,这也是一个`bug得解决。同时还进一步将代码进行优化,用到filter达到历史去重得效果,即判断新拿到得搜索关键词是否与已有得搜索历史中的搜索关键词相同,同则过滤掉先前的那个,并使用到unshift向数组开头增加这个作为新的历史记录。

历史缓存
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码8
登录后复制

解析:虽然上一步将拿到的搜索记录存入到了搜索历史,但是还不能显示出来,让数据源拿到数据,这里要做一个历史缓存的操作。onShow为监听页面显示,每次在搜素建议功能后进行点击歌名出现搜索结果栏时触发,此时将上一步拿到的historygetStorageSync进行本地缓存,使得在刷新或者跳转时,不会讲搜索历史丢失,一直保存下来。

删除历史
<!-- 搜索建议 --><view class="{{showSongResult ? 'search_suggest' : 'header_view_hide'}}">复制代码9
登录后复制

解析:showModal() 方法用于显示对话窗,当点击删除按钮时触发,显示出确认清空全部历史记录的窗口,并有两个点击按钮:确认取消;当点击确认时,将history数组中的内容重置为空,即达到清空搜索历史中的数据的功能;同时也需要将此时没有数据的的搜索历史进行缓存。点击取消,提示窗消失,界面不会发生任何变化。

8.歌曲跳转播放播放传值跳转播放界面
<!-- 搜索结果 --><view class="{{showSearchResult ? 'header_view_hide' : 'search_result_songs'}}">复制代码0
登录后复制

解析:handlePlayAudio绑定在每天搜索结果上,即点击搜索建议后完成搜索结果功能显示出搜索结果栏,点击每一天搜索结果都可以触发handlePlayAudio。前面也讲到过bindtap是带有参数返回,携带额外信息dataset,event本身会有一个currentTarget属性,data-id="{{item.id}}"的作用跟上面的搜索建议内的歌曲点击事件是同样的效果,item.id为执行搜索结果时接口返回给searchResult的数据,也就是搜索结果中每首歌曲各自对应的id。当点击搜索结果内的某一首歌,即将这首歌的id传给event中的dataset,数据名为dataset里的id。此时我们定义一个musicId,将event里面的歌曲id赋值给musicId,用 wx.navigateTo跳转到播放界面,同时将musicId作为播放请求接口需要的传入数据。 查看打印数据e:

9.search功能源码分享

wxml

<!-- 搜索结果 --><view class="{{showSearchResult ? 'header_view_hide' : 'search_result_songs'}}">复制代码1
登录后复制

wxss

<!-- 搜索结果 --><view class="{{showSearchResult ? 'header_view_hide' : 'search_result_songs'}}">复制代码2
登录后复制

js

<!-- 搜索结果 --><view class="{{showSearchResult ? 'header_view_hide' : 'search_result_songs'}}">复制代码3
登录后复制

api.js

<!-- 搜索结果 --><view class="{{showSearchResult ? 'header_view_hide' : 'search_result_songs'}}">复制代码4
登录后复制
总结

其实一点一点的捋清楚会发现也不是很难操作,首先思路要清晰,知道每一个功能是什么作用,同时在调试是时候去发现一些bug,再去对代码进行优化。关于搜索这个功能用处广泛,希望本次的分享能给大家带来一点用处。

相关学习推荐:微信公众号开发教程,javascript视频教程

以上就是那些年,微信小程序仿网易云音乐有关实时搜索功能的详细内容,更多请关注9543建站博客其它相关文章!

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:yii怎么记录api接口执行时间
下一篇:推荐10款服务端接收源码(收藏)

发表评论

关闭广告
关闭广告