vue2学习仿qq音乐的心路历程

随着互联网的高速发展,技术不断的更新迭代,web这一领域技术发展更是快的不行,几年前风靡全球的jQuery,现在看来也遇到了瓶颈,现在web更是讲究框架模块化开发,react/vue/angular等框架就是这web发展所需的时代产物,好了,感慨就到这里吧。。。。。。第一次发博,算是学习之路的一个记录

 

1.这里主要记录一下qq音乐接口变化的问题,之前qq音乐歌曲地址是不需要vkey这样的参数的,视频上讲的只能指引你,真要掌握、吃透还得靠自己去不断查找,不断发现。所以说,朋友们,发现自己不懂的问题,才是最重要的。


这里贴出视频里suggest.vue的代码

searchMore() {if (!this.hasMore) {return}this.page++search(this.query, this.page, this.showSinger, perpage).then((res) => {if (res.code === ERR_OK) {this.result = this.result.concat(this._genResult(res.data))this._checkMore(res.data)}})}
_genResult(data) {let ret = []if (data.zhida && data.zhida.singerid) {ret.push({...data.zhida, ...{type: TYPE_SINGER}})}if (data.song) {ret = ret.concat(this._normalizeSongs(data.song.list))}return ret}
_normalizeSongs(list) {let ret = []list.forEach((musicData) => {if (musicData.songid && musicData.albummid) {ret.push(createSong(musicData))}})return ret}

然后是qq音乐接口变化后(需要vkey等参数),缺什么,我们就去找什么

1.首先到api/singer.js下加一个获取vkey的方法

export function getSongVkey (songmid) { // 获取歌曲的vkeyconst url = '/getVkey'const data = Object.assign({}, commonParams, {callback: 'get002341',jsonpCallback: 'get002341',loginUin: 0,hostUin: 0,format: 'jsonp',platform: 'yqq',needNewCode: 0,data: `{"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"5416664912","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"5416664912","songmid":["${songmid}"],"songtype":[0],"uin":"0","loginflag":1,"platform":"20"}},"comm":{"uin":0,"format":"json","ct":20,"cv":0}}`})return axios.get(url,{params:data}).then((res) => {return Promise.resolve(res.data)}).catch((e) => {console.log(e)})
}

2.然后到webpack.dev.conf.js中去设置代理请求数据

app.get('/getVkey', function (req, res) {//这里的路径是给前端发送请求的urlconst url = 'https://u.y.qq.com/cgi-bin/musicu.fcg'// axios发送get请求,可以自己配置configaxios.get(url, {headers: {referer: 'https://y.qq.com/',host: 'u.y.qq.com'},//  params是即将与请求一起发送的url参数,无格式对象/URLSearchParams对象params: req.query}).then((response) => {let rest = response.dataif(typeof rest === 'string') {let reg = /^\w+\(({[^()]+})\)$/let matches = rest.match(reg)if(matches) {rest = JSON.parse(matches[1])}}res.json(rest)}).catch((e) => {console.log(e)})})

这里是我们需要的url

 以及需要的参数字段及内容

 重点是域名后面的参数,不要太刻意关注域名,这是音乐文件的真实地址

 common/js/song.js  createSong方法参数内容变化

export function createSong(musicData, filename, vkey) {return new Song({id: musicData.songid,mid: musicData.songmid,singer: filterSinger(musicData.singer),name: musicData.songname,album: musicData.albumname,duration: musicData.interval,image: `https://y.gtimg.cn/music/photo_new/T002R300x300M000${musicData.albummid}.jpg?max_age=2592000`,url: `http://dl.stream.qqmusic.qq.com/${filename}?guid=5416664912&vkey=${vkey}&uin=0&fromtag=66`})
}

2.最后是自己不断的摸索,不断的查找,然后到思否上提问,才找到解决问题的关键所在

先贴出自己suggest.vue的三个函数变化

_normalizeSongs(list, callback) {if(!list) {return}let rest = []let index = 1list.forEach((musicData) => {if(musicData.songid && musicData.albummid) {let promise = getSongVkey(musicData.songmid) //获取歌曲filename及vkeypromise.then((res) => {if(res.code === ERR_OK) {const filename = res.req_0.data.midurlinfo[0].filenameconst vkey = res.req_0.data.midurlinfo[0].vkeyconst newSong = createSong(musicData, filename, vkey)// console.log(newSong)rest.push(newSong)  //将获取到的歌曲加入到数组中if(index === list.length) {callback && callback(rest)}index++}})}})}
_genResult(data, callback) {let rest = []if(data.zhida && data.zhida.singername) {rest.push({...data.zhida,...{type: TYPE_SINGER}})}if(data.song) {this._normalizeSongs(data.song.list, (restdata) => {rest = rest.concat(restdata)callback && callback(rest)})}}
search() {this.hasMore = truethis.page = 1   //当query发生改变时,page重置为1this.$refs.suggest.scrollTo(0, 0)search(this.query, this.page, this.showSinger, Perpage).then((res) => {if(res.code === ERR_OK) {this._genResult(res.data, (rest) => {// console.log(rest)this.result = rest})this._checkMore(res.data)}})}

其中searchMore方法也有小小变化

searchMore() {if(!this.hasMore) {return}this.page++search(this.query, this.page, this.showSinger, Perpage).then((res) => {if(res.code === ERR_OK) {this._genResult(res.data, (rest) => {this.result = this.result.concat(rest) //把新搜索到的数据拼接到之前搜索到的数据中})this._checkMore(res.data)}})}

!!!重点来了,要考的

对比之后会发现,视频里的_normalizeSongs方法和_genResult方法会有一个return的值,我的问题就在这里,因为qq音乐接口参数变化后,需要用到getSongVkey这个方法,这个方法返回的是promise对象,然而我要在循环里执行这个异步方法,没办法在循环外return想要的结果,最后在思否上提问,得到道友的解惑,通过callback这个参数得到我想要的return,在promise.then()中call&&callback(rest),自己想要的结果就会被这个rest收留,然后在其他函数里进行下一步操作,总结说来视频里的某个函数return的结果也是被另外的函数当做参数来进行下一步操作,方法不同,思路不同,得到的结果却是相同的,关键是怎么去看待问题,才能采取相应的方法去应对;思否提问地址https://segmentfault.com/q/1010000016912296,感兴趣的可以去看看,漫漫学习路,记一笔。。。

 
 
 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部