内容均为《Vue2.0开发企业级移动端音乐Web App 》学习笔记
包括歌单页面的布局介绍、Vuex 实现路由数据通讯、歌单详情页数据抓取和处理。
8-1 歌单详情页布局介绍及Vuex实现路由数据通讯
1、创建子路由 src\router\index.js
import Disc from 'components/disc/disc.vue'
//配置路由
{
path:'/recommend',
component:recommend,
name:'推荐',
children:[
{
path:'/recommend/:id',
component:Disc
}
]
},
复制代码
2、在vuex中管理歌单数据 state
disc:{},//推荐的歌单
复制代码
getters
export const disc=(state)=>state.disc//推荐的歌单
复制代码
mutation-types
export const SET_DISC='SET_DISC'//改变歌单常量
复制代码
mutations.js
//改变当前的推荐歌单
[types.SET_DISC](state,disc){
state.disc=disc
}
复制代码
3、添加路由容器 recommend.vue
<router-view></router-view>
复制代码
4、给推荐列表绑定点击事件
<li class="item" v-for='(item,index) in recommendList' :key="index" @click="selectItem(item)">
复制代码
5、一旦点击时,改变路由,并且调起一个mutation
selectItem(item){
this.$router.push(`/recommend/${item.dissid}`);
this.set_disc(item);
}
复制代码
8-2 歌单详情页数据抓取 components\disc\disc.vue
1、获取到vuex的歌单数据disc
import {mapGetters} from 'vuex'
...mapGetters(['disc']),
复制代码
2、发送请求,获取到歌单详情数据
设置代理(config\index.js)
//获取到推荐页面的歌单部分
'/api/getSongList':{
target:'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg',
secure:false,
changeOrigin:true,
bypass:function(req,res,proxyOptions){
req.headers.referer='https://y.qq.com/',
req.headers.host='c.y.qq.com'
},
pathRewrite:{
'^/api/getSongList': ''
}
}
复制代码
定义api方法(api\recommend.js)
//获取到推荐的详情页面的数据
export const getSongList=function(disstid){
return new Promise(function(resolve,reject){
let url='/api/getSongList';
let data=Object.assign({},commonParams,{
uin: 0,
format: 'json',
notice: 0,
needNewCode: 1,
new_format: 1,
pic: 500,
disstid, //关键数据
type: 1,
json: 1,
utf8: 1,
onlysong: 0,
picmid: 1,
nosign: 1,
song_begin: 0,
platform: 'h5',
song_num: 100,
_: +new Date()
})
axios.get(url,{params:data}).then(res=>{
resolve(res.data)
}).then(err=>{
reject(err)
})
})
}
复制代码
发送请求
created(){
this._getSongList()
},
_getSongList(){
//当刷新的时候,让路由跳到上一级
if(!this.disc.dissid){
this.$router.push('/recommend');
}
getSongList(this.disc.dissid).then(res=>{
if(res.code==ERR_OK){
//做数据处理
this.songs=this._normalrizeSongs(res.cdlist[0].songlist)
}
})
},
//同歌手详情页,歌曲的播放url中的vkey需要发送请求获取,同时将处理好的数据封装新的Song实例
_normalrizeSongs(list){
let ret = []
list.forEach(musicData => {
if(musicData.id && musicData.album) {
getMusicVkey(musicData.mid).then(res=>{
if(res.code===ERR_OK){
ret.push(creatSongList(musicData,res.data.items[0].vkey))
}
})
}
});
return ret
}
复制代码
src\common\js\song.js
//抽象出一个工厂方法:传入musicData对象参数,实例化一个Song
export default function createSong(musicData,songVkey){
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`,
//播放源这里的songVkey需要动态获取。
url: `http://dl.stream.qqmusic.qq.com/C400${musicData.songmid}.m4a?vkey=${songVkey}&guid=6319873028&uin=0&fromtag=66`
})
}
复制代码
8-3 歌单详情页应用
引入musicList组件,并且传入相关的数据
<musicList :bgImage="bgImage" :songs="songs" :title="title" ></musicList>
复制代码
computed:{
...mapGetters(['disc']),
bgImage(){
return this.disc.imgurl
},
title(){
return this.disc.dissname
}
},
复制代码