包括排行榜布局介绍、排行榜数据抓取和应用、榜单详情页布局介绍、Vuex 实现路由数据通讯、榜单详情页数据抓取和应用。
9-1 排行页面布局介绍及排行榜数据抓取
页面布局 components\rank\rank.vue
<div class="rank" ref='rank'>
<scroll class="toplist" :data="topList" ref="scroll">
<ul>
<li class="item" v-for="(item,index) in topList" :key='index'>
<div class="icon">
<img width="100" height="100" v-lazy="item.picUrl">
</div>
<ul class="songlist">
<li class="song" v-for="(song,index) in item.songList" :key="index" @click="selectItem(item)">
<span>{{index+1}} </span><span>{{song.singername}}- {{song.songname}}</span>
</li>
</ul>
</li>
</ul>
</scroll>
</div>
复制代码
定义排行榜的列表和排行榜的列表详情的 api api\rank.js
import { commonParams,options} from "api/config.js";
import jsonp from "common/js/jsonp.js";
export function getRankList(){
const url = "https://c.y.qq.com/v8/fcg-bin/fcg_myqq_toplist.fcg"
let data=Object.assign({},{
platform: 'h5',
needNewcode: 1
},commonParams)
return jsonp(url,data,options)
}
//获取排行绑的歌单
export function getRankDetail(topid){
const url = "https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.fcg"
let data=Object.assign({},commonParams,{
topid,
needNewCode: 1,
uin: 0,
tpl: 3,
page: 'detail',
type: 'top',
platform: 'h5'
})
return jsonp(url,data,options)
}
复制代码
做底部子适应处理
import {playlistMixin} from '../../common/js/mixin'
mixins:[playlistMixin],
//底部自适应
handlePlayList(playlist){
let bottom=playlist.length ? '60' : 0;
this.$refs.rank.style['bottom']=`${bottom}px`
this.$refs.scroll.refresh();
}
复制代码
9-2 排行页排行榜数据应用
在data上面维护一个topList,在create时,获取到列表的数据
created(){
this._getRankList()
},
_getRankList(){
getRankList().then(res=>{
if(res.code==ERR_OK){
this.topList=res.data.topList
}
})
},
复制代码
9-3 榜单详情页布局介绍及Vuex实现路由数据通讯
给每一项的li绑定点击事件
<li class="song" v-for="(song,index) in item.songList" :key="index" @click="selectItem(item)">
复制代码
点击的时候去到榜单详情页面榜单详情页是榜单列表页的一个子路由,我们需要在src\router\index.js配置相应的路由
import rankDetail from 'components/rank-detail/rank-detail.vue'
{
path:'/rank',
component:rank,
name:'排行',
children:[
{
path:'/rank/:id',
component:rankDetail
}
]
},
复制代码
因为我们需要列表页面传递多个数据到列表详情页,在这里,我们用vuex来管理传递过来的参数
store\state.js
rank:{},//排行榜的歌单
复制代码
store\getters.js
//排行榜的歌单
export const rank=(state)=>state.rank;
复制代码
store\mutation-types.js
//排行版的歌单
export const SET_RANK='SET_RANK'
复制代码
store\mutations.js
//改变排行榜的歌单
[types.SET_RANK](state,rank){
state. rank=rank
}
复制代码
在点击榜单列表时,触发一个mutation(rank\rank.vue)
import {mapMutations} from 'vuex'
...mapMutations({
set_rank:'SET_RANK'
}),
selectItem(rank){
this.$router.push({
path:`/rank/${rank.id}`
});
this.set_rank(rank);
},
复制代码
9-4 榜单详情页数据抓取和应用
components\rank-detail\rank-detail.vue,引入musicList,并且传递对应的数据
<musicList :songs="topList" :bgImage="bgImage" :title="title"></musicList>
复制代码
在data中维护一个topList用来存榜单详情的列表
computed:{
...mapGetters(['rank']),
bgImage(){
//让第一首歌作为封面
if(this.topList.length){
return this.topList[0].image
}
return this.rank.picUrl
},
title(){
return this.rank.topTitle
}
},
复制代码
在create时做路由处理(避免在页面刷新的时候,找不到this.rank.id)。获取到当前的播放列表
created(){
if(!this.rank.id){
this.$router.push({
path:'/rank'
})
}else{
this._getTopListDetail()
}
},
复制代码
_getTopListDetail(){
getRankDetail(this.rank.id).then(res=>{
if( res.code==ERR_OK){
this.topList=this._normalrezie(res.songlist);
}
})
},
复制代码
对得到的数据进行格式处理
import createSong from 'common/js/song.js'
import {getMusicVkey} from 'api/singer.js'
_normalrezie(list){
let ret = []
list.forEach(item => {
let musicData=item.data;
if(musicData.songid && musicData.songmid){
//调用接口获取到Vkey
getMusicVkey(musicData.songmid).then((res)=>{
if(res.code==ERR_OK){
let songVkey=res.data.items[0].vkey
ret.push(createSong(musicData,songVkey));
}
})
}
});
return ret;
}
复制代码
9-5 带排行的song-list组件扩展和应用
给 song-list加上图标结构,样式以及图片
添加props字段为rank。当rank为ture时才展示图标,默认不展示
rank:{
type:Boolean,
default:true
}
复制代码
绑定两个方法,getRankCls,getRankText分别获取到当前项的图标和当前列表的文本
<div class="rank" v-show="rank" >
<span :class="getRankCls(index)">{{getRankText(index)}}</span>
</div>
复制代码
getRankCls(index){
if(index<=2){
return `icon icon${index}`
}else{
return 'text'
}
},
getRankText(index){
if(index > 2) {
return index + 1
}
}
复制代码
music-list.vue作为中间组件,也需要添加一个props,并且向song-list传递rank
rank:{
type:Boolean,
default: false
}
复制代码
<song-list :songs="songs" :rank="rank" @select='selectItem'></song-list>
复制代码
在rank-detail.vue中,定义传入rank给music-list.vue
isrank:true
复制代码
<musicList :songs="topList" :bgImage="bgImage" :title="title" :rank="isrank"></musicList>
复制代码