# wechat_wangyiyunyinyue **Repository Path**: abcdfdewrw/wechat_wangyiyunyinyue ## Basic Information - **Project Name**: wechat_wangyiyunyinyue - **Description**: 仿网易云音乐小程序 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2022-09-07 - **Last Updated**: 2024-05-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 仿网易云音乐 ## 运行 1、需要微信开发者工具,通过此软件打开项目
2、manster_server 文件夹是服务器,需要在终端中输入`node app.js `启动
## 目录分析 ![image-20220906153228469](README.assets/image-20220906153228469.png) ### pages文件夹 pages文件主要是用来存放各页面
![image-20220906153511151](README.assets/image-20220906153511151.png) #### goto 是否去往登录页面 ![image-20220906153937990](README.assets/image-20220906153937990.png) 思路:有两种情况,一种是用户已经登录;一种是用户没有登录;
用户登录了,这个页面头像就是用户头像(用户登录了是会把信息存储在Storage中,我们从这里获取到用户的头像),按钮名字是 "退出",退回到个人中心;
用户没有登录,这个页面头像就是默认的头像,按钮名称 ”登录“,点击按钮跳转到登录页面
> this.setDate({ }) // 用于修改页面初始数据
> > wx.removeStorageSync('userInfo'); // 清除用户记录
> > wx.reLaunch({ }) // 关闭所有页面,打开到应用内的某个页面
> > wx.navigateTo({ }) // 保留当前页面,跳转到应用内的某个页面
#### index 首页 ![image-20220906160218014](README.assets/image-20220906160218014.png) ![image-20220906160232686](README.assets/image-20220906160232686.png) 【功能】: 1、搜索音乐 `bindtap="searchMusic"`
2、每日推荐 `bindtap="searchMusic"`
3、推荐歌单 `bindtap="toPlayList"`
4、排行榜 `bindtap="toSongDetail `
【问题】调用排行榜接口的时候,我们获取5列排行榜的音乐信息,每列排行榜我们只取前3条音乐信息,如果我们等到全面获取完之后,再去修改页面初始排行榜内容,可能用户等待时间过程,出现白板现象,用户体验感差。
【优化】我们获取到1列排行榜音乐信息,取前三行,我们就直接修改初始化数组,之后又获取到前2列排行榜音乐信息,又重新修改初始化数组,用户所看到的就是陆陆续续的去加载,不会出现白板的情况,用户体验感好了,但是修改次数多了。
#### login 登录页面 ![image-20220906164141142](README.assets/image-20220906164141142.png) 【实时获取表单内容】:给input绑定事件,参数为event,包含输入的全部信息,我们通过 `event.currentTarget.id `获取输入框是“手机输入框” 还是 “密码输入框” ;通过`event.detail.value` 获取输入的具体值。
【登录按钮】:前端验证,验证通过就调用接口,如果登录成功,则把数据缓存到Storage中去,跳转到个人中心
> wx.showToast({ }) // 显示消息提示框
> > wx.setStorageSync('key',data) // 将数据存储在本地缓存中指定的 key 中
> > wx.reLaunch({ }) // 关闭所有页面,打开到应用内的某个页面
#### personal 个人中心 ![image-20220906165633586](README.assets/image-20220906165633586.png) 【游客登录】:如果头像没有显示出来,说明用户没有登录,还是游客状态,点击游客头像跳转到 goto是否登录界面
#### playlist 歌曲详细列表 ![image-20220906171252192](README.assets/image-20220906171252192.png) 在index页面的时候,给每个推荐歌曲中的图片添加一个点击事件 `bindtap="toPlayList"`,跳转到这个歌单详情页的时候,携带每个歌单的id,从而显示相应的歌单歌曲
``` /* 跳到推荐歌单页面 */ toPlayList(event){ // console.log(event) wx.navigateTo({ url:'/pages/playlist/playlist?id='+event.currentTarget.id }) }, ``` ``` // playlist 获取index页面传过来的id onLoad: function (options) { // console.log(options) // 用来接受query传参 // 获取歌单歌曲 //获取歌单id let listid = options.id; this.setData({ listid: listid }) ``` 【获取歌单歌曲】:调用服务器接口,使用模板字符串显示到页面
【跳转到songDetail页面】:给每个歌单中的每个歌曲添加点击事件,点击的时候跳转到songDetail,并且同时传递歌曲id;
【订阅songDetail页面发布的消息】:实现歌单歌曲的上一首和下一首(与每日推荐那里是一样的)
#### recommendSong 每日推荐页 ![img](README.assets/8a40b724bb3346e9958589113ecf388e.png) 每日推荐页面要用户先登录才可以进来;
动态修改日期;
【调用推荐歌曲接口】:调用接口获取每日推荐的歌曲信息,存储到recomentList数组中
【点击每日推荐歌曲播放】:获取点击歌曲的序号index,存储起来。并携带歌曲id跳转到songDetail页面;
【上一首/下一首音乐切换】:先接收播放页songDetail中发过来的歌曲上下切换,看是上一首还是下一首。如果是发送的是要上一首pre,那我们就index-1,但是要注意,如果此时的歌曲是第一首歌,上一首就是最后一首;如果发送的是下一首next,那我们就要index+1,但要注意,如果此时的歌曲是最后一首,那么下一首就是第一首歌。修改好index后,把该序号的歌曲的id发送给`songDeatil(recommentList[index].id)`
#### songDetail 播放页 ![image-20220906173912529](README.assets/image-20220906173912529.png) 【音乐播放/暂停功能】:通过isPlay标签来标记音乐此时是播放还是暂停。如果isPlay是true那么就是播放,使用音乐链接来播放(这里可能是第一次刚点击歌曲,那么我们就通过音乐id去发送请求,获取该音乐的链接),反之就是暂停。
【切歌】:发送切割类型给recommendSong页面,如果点击的是上一首则是就发送pre,如果是下一首则就发送next;之后recommendSong页面拿到之后会进行处理,返回一个歌曲id,再去播放该歌曲。
【歌词滚动】:
1、getLyric :根据音乐id获取歌词
``` 得到歌词样式 { "lrc": { "version": 7, "lyric": "[00:00.000] 作词 : TetraCalyx\n[00:01.000] 作曲 : 蔡近翰Zoe(HOYO-MiX)\n[00:02.000] 编曲 : 宫奇Gon(HOYO-MiX)/杨启翔Frex(HOYO-MiX)\n[00:03.08]Life blooms like a flower\n[00:07.00]far away or by the road\n[00:10.15]waiting for the one\n[00:13.22]to find the way back home\n[00:17.15]Rain falls a thousand times\n[00:21.02]No footprints of come-and-go\n[00:24.14]You who once went by\n[00:28.05]where will you belong\n[00:30.10]I feel your sigh and breath\n[00:33.24]In the last blow of wind\n[00:38.08]Not yet for the story on the last page\n[00:42.18]It's not the end\n[00:45.17]Life blooms like a flower\n[00:49.07]far away or by the road\n[00:52.23]waiting for the one\n[00:56.04]to find the way back home\n[00:59.22]Time flows across the world\n[01:03.09]There is always a longer way to go\n[01:07.21]Till I reach your arms\n[01:10.07]a Madder there for you\n[01:13.24]Up against the stream\n[01:17.15]waterways will join as one\n[01:21.00]Tracing to the source\n[01:24.17]No more strayed or lost\n[01:26.22]You will see petals fly\n[01:30.10]when lament becomes carol\n[01:34.19]Could you please hear my voice\n[01:37.11]that hungers for a duo\n[01:43.69]Life blooms like a flower\n[01:45.18]far away or by the road\n[01:49.08]waiting for the one\n[01:52.16]to find the way back home\n[01:56.09]Time flows across the world\n[01:59.21]There is always a longer way to go\n[02:04.08]Till I reach your arms\n[02:06.19]a Madder there for you\n[02:37.00]Life blooms like a flower\n[02:40.11]far away or by the road\n[02:44.01]waiting for the one\n[02:47.08]to find the way back home\n[02:51.00]Time flows across the world\n[02:54.15]There is always a longer way to go\n[02:59.01]Till I reach your arms\n[03:01.11]a Madder there for you\n[03:03.720] 人声录音 Recording:徐威Aaron Xu\n[03:06.429] 混音/母带 Mixing&Mastering Engineer:宫奇Gon(HOYO-MiX)\n[03:09.138] 制作人 Producer:蔡近翰Zoe(HOYO-MiX)\n[03:11.847] 特别鸣谢 Special Thanks:周深工作室\n[03:14.556] 出品 Produced by:HOYO-MiX\n" } } ``` 2、使用formatLyric()对歌词进行整理
(1)先通过\n进行切割;
(2)此时歌词变成一行一行的,一行中有 时间,还有歌词,我们需要分别把每行的这两部分给拆分出来,并且把时间转换为秒S的形式,以对象的形式存放在`lyric数组`中
``` lyric[ { text: " 作词 : TetraCalyx", time: 0 }, { text: " 作曲 : 蔡近翰Zoe(HOYO-MiX)", time: 1 }, { text: " 编曲 : 宫奇Gon(HOYO-MiX)/杨启翔Frex(HOYO-MiX)", time: 2 }, { text: "Life blooms like a flower", time: 4 }, { text: "far away or by the road", time: 7 }, { text: "waiting for the one", time: 11 },{ text: "to find the way back home", time: 14 }, ... ] ``` (3) 判定显示哪句歌词。将歌词数组lyric数组进行遍历,如果当前歌曲播放的时间等于歌词数组中time的时间,就将歌词换成为这一句;这样当上一句完全唱完的时候再进行切换。把确定好的歌词放入`currentLyric`中,页面显示
#### video 视频页 ![image-20220906193537650](README.assets/image-20220906193537650.png) 【调用视频列表接口】:默认是第一个导航标签的接口(传递它的id即可),调用接口获取视频列表,存放到数组中去。
【点击播放/继续播放回调】:获取点击视频的vid,把每一个视频实例放到this中存起来,方便下次的vid对比。如果新旧视频的vid相同,则继续播放,如果不相同就关闭旧的视频,播放新视频。
【视频播放进度回调】:判断记录播放时长数组中是否又当前视频的播放记录(通过id来判断),如果有,在原有的播放记录中修改播放时间为当前播放时间,如果没有,需要在数组中添加当前视频的播放对象。
【视频播放结束回调】:找到播放完的视频下标,然后再存放视频播放进度中删除,然后再更新数据。
【上拉刷新】:模拟的数据,把模拟数据放到视频列表的最前面
【下拉刷新】:重新发送请求,获取最先的视频,存放到视频列表中;

【优化】:视频我们先用视频图片作为封面,当我们点击某个视频的时候,判断点击的那个图片id是否与视频封面的id相同,如相同我们就把视频地址赋给src,否则还是图片
#### search 搜索页 ![image-20220906174747118](README.assets/image-20220906174747118.png) 【搜索框关键字模糊匹配数据】:如果输入框发生变化时,触发`handleInputChange`回调,使用函数节流,等300s后发送请求,根据输入框的数据去进行模糊搜索。如果你没有输入数据,则没有反应,你输入数据,则会根据你所输入的数据,去发送请求,请求回来的数据取前10条存放在一个数组中,显示那个数组。如果历史记录有你输入的数据,而你又输入了一次,因此它又会存到历史记录中去,所以,你每输入一条数据的时候,先在历史记录中去判断是否有相同的历史记录,如果有我们就删掉原先的,添加新的。之后再把历史记录存放到storage中去。
【清除搜索内容】:也就是把初始数据清空
【删除搜索历史记录】:在storage中移除搜索历史记录
【点击热搜索中的歌曲进行搜索】:它是会把热搜索中的歌曲,保存起来,在输入框中显示,之后发送请求,返回十条歌曲。
【获取历史记录】:从本地Storage中获取历史记录
【跳转到歌曲详情页面】:携带该歌曲的id跳转到播放页
### static文件夹 static主要用来存放静态资源如,图片,字体等
![image-20220907170818874](README.assets/image-20220907170818874.png) ### utils文件夹 主要用来存放服务器配置以及向服务器发送请求的文件
![image-20220907171135867](README.assets/image-20220907171135867.png) ### app.json ![image-20220907174601174](README.assets/image-20220907174601174.png) 这几个文件主要是用于设置整个小程序页面的,比如app.json里面存放的是我们所写的页面的显示顺序,小程序标题颜色等。