第9章 排行榜及详情页开发

包括排行榜布局介绍、排行榜数据抓取和应用、榜单详情页布局介绍、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>
复制代码

github chapter9

转载于:https://juejin.im/post/5d25b9ad6fb9a07ed064da91

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值