前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记。

项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star。


歌单及详情页 排行榜及详情页
一、歌单详情页开发

歌单详情页布局介绍及Vuex实现路由数据通讯

  • components->disc目录下:创建disc.vue
  • router->index.js中:给Recommend添加二级子路由Disc
    {
    path: '/recommend',
    component: Recommend,
    children: [
    {
    path: ':id',
    component: Disc
    }
    ]
    }
  • recommend.vue中:
  1. 添加路由容器

    <router-view></router-view>
  2. 给歌单列表添加点击事件
    @click="selectItem(item)"
  3. 定义selectItem()实现路由跳转
    selectItem(item) {
    this.$router.push({
    path: `/recommend/${item.dissid}`
    })
    }
  • 使用vuex传递歌单数据
  1. state.js中:添加歌单对象

    disc: {}
  2. mutation-type.js中:定义type常量
    export const SET_DISC = 'SET_DISC'
  3. mutation.js中:创建更改函数
    [types.SET_DISC](state, disc){
    state.disc = disc
    }
  4. getters.js中:定义数据映射
    export const disc = state => state.disc
  • recommend.vue中:使用mapMutations修改disc

    import {mapMutations} from 'vuex'
    
    ...mapMutations({
    setDisc: 'SET_DISC'
    }) selectItem(item) {
    this.$router.push({
    path: `/recommend/${item.dissid}`
    })
    this.setDisc(item) //更改state中的disc
    }
  • disc.vue中:通过mapGetters获取到date中的disc

    import {mapGetters} from 'vuex
    
    computed: {
    ...mapGetters([
    'disc'
    ])
    }
  • 传递数据:获取数据在computed里面,设置数据在methods里面

歌单详情页数据抓取

  • api->recommend.js中:添加getSonglist接口

    export function getSongList (disstid) {
    const url = '/api/getSongList' const 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()
    }) return axios.get(url, {
    params: data
    }).then((res) => {
    return Promise.resolve(res.data)
    })
    }
  • 因为数据也经过加密,在webpack.dev.config.js中模仿header:
    app.get('/api/getSongList', function (req, res) {
    var url = 'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg'
    axios.get(url, {
    headers: {
    referer: 'https://y.qq.com/',
    host: 'c.y.qq.com'
    },
    params: req.query
    }).then((response) => {
    res.json(response.data)
    }).catch((e) => {
    console.log(e)
    })
    })

    注意:后端配置之后,一定要重新启动!!!

歌单详情页数据的处理和应用

  • 调用getSongList()方法获取数据,在created()时获取

    import {getSongList} from '@/api/recommend'
    
    _getSongList () {
    if(!this.disc.dissid){ //在歌单详情页强制刷新后,即没有获得id时,回退到推荐页面
    this.$router.push('/recommend')
    return
    }
    getSongList(this.disc.dissid).then((res) => {
    if (res.code === ERR_OK) {
    this.songs = this._normalizeSongs((res.cdlist[0].songlist))
    // console.log(res)
    // console.log(res.cdlist[0].songlist)
    // console.log(this._normalizeSongs(res.cdlist[0].songlist))
    }
    })
    }
  • 获得数据后,在methods中对数据进行一些处理
  1. 同歌手详情页,歌曲的播放url中的vkey需要发送请求获取,同时将处理好的数据封装新的Song实例

    import {ERR_OK} from '@/api/config'
    import {creatSongList} from '@/common/js/song'
    import {getMusic} from '@/api/singer' _normalizeSongs (list) {
    let ret = []
    list.forEach((musicData) => {
    if (musicData.id && musicData.album) {
    // ret.push(creatSongList(musicData))
    getMusic(musicData.mid).then((res) => {
    // console.log(res)
    if(res.code === ERR_OK){
    // console.log(res.data)
    const svkey = res.data.items
    const songVkey = svkey[0].vkey
    const newSong = creatSongList(musicData, songVkey)
    ret.push(newSong)
    }
    })
    }
    })
    return ret
    }

    其中:调用getMusic()获取播放地址的vkey,调用creatSongList()实例化Song对象

  2. common->js->song.js中: 创建creatSongList()
    export function creatSongList (musicData, songVkey) {
    return new Song({
    id: musicData.id,
    mid: musicData.mid,
    singer: filterSinger(musicData.singer),
    name: musicData.name,
    album: musicData.albumname,
    duration: musicData.interval,
    image: `https://y.gtimg.cn/music/photo_new/T002R300x300M000${musicData.album.mid}.jpg?max_age=2592000`,
    //注意guid以实时数据为主
    url: `http://ws.stream.qqmusic.qq.com/C400${musicData.mid}.m4a?vkey=${songVkey}&guid=6319873028&uin=0&fromtag=66`
    })
    }
二、排行榜及详情页开发

排行榜数据抓取

  • 在api目录下:创建rank.js添加获取数据的接口

    import jsonp from '@/common/js/jsonp'
    import {commonParams, options} from './config' export function getTopList() {
    const url = "https://c.y.qq.com/v8/fcg-bin/fcg_myqq_toplist.fcg" const data = Object.assign({}, commonParams, {
    platform: 'h5',
    needNewcode: 1
    }) return jsonp(url, data, options)
    }
  • rank.vue中:调用getTopList()方法获取数据,在created()时获取
    import {getTopList} from '@/api/rank'
    import {ERR_OK} from '@/api/config' created() {
    this._getTopList()
    },
    methods: {
    _getTopList() {
    getTopList().then((res) => {
    if(res.code === ERR_OK){
    console.log(res.data.topList)
    }
    })
    }
    }

排行榜数据应用

  • 在data中维护数据

    topList: []
  • 获取数据后赋值
    this.topList = res.data.topList
  • 将数据填入DOM:应用scroll组件替换父元素<div>并传入topList数据实现滚动
    <scroll class="top-list" :data="topList">
  • 优化:应用loading组件,设置当topList没有内容时显示loading
  • 优化:应用mixin,实现播放器底部适配

榜单详情页布局及Vuex实现路由数据通讯

  • 路由的跳转
  1. router->index.js中:设置Rank的二级路由

    import TopList from '@/components/top-list/top-list' 
    
    {
    path: '/rank',
    component: Rank,
    children: [
    {
    path: ':id',
    component: TopList
    }
    ]
    }
  2. rank.vue中:添加路由容器,给列表添加点击事件,触发路由的跳转

    <router-view></router-view>
    @click="selectItem(item)"
    selectItem(item) {
    this.$router.push({
    path: `/rank/${item.id}`
    })
    }
  • Vuex传递数据
  1. state.js中:定义数据

    topList: {}
  2. mutation-types.js中:定义type常量
    export const SET_TOP_LIST = 'SET_TOP_LIST'
  3. mutations.js中:添加修改topList的方法
    [types.SET_TOP_LIST](state, topList){
    state.topList = topList
    }
  4. getters.js中:添加topList的数据映射
    export const topList = state => state.topList
  • 写入和获取state数据
  1. rank.vue中:通过mapMutations写入数据

    import {mapMutations} from 'vuex'
    
    this.setTopList(item)
    
    ...mapMutations({
    setTopList: 'SET_TOP_LIST'
    })
  2. top-list.vue中:通过mapGatters拿到数据
    import {mapGetters} from 'vuex'
    
    computed: {
    ...mapGetters([
    'topList'
    ])
    }

    剩下的就是获取数据用computed,设置数据用methods

榜单详情歌曲数据的抓取

  • 需求:榜单本身的背景图不好看,想要抓取榜单详情歌曲的图片作为背景图
  • 问题:原请求是Ajax请求,不能跨域,但也支持jsonp请求,只是没有格式化不方便查看数据
  • 解决: 在线网站www.bejson.com中格式化为json文件
  • 因为这块数据QQ音乐也做了加密,这里抓取数据同歌单详情页方式
  1. api->rank.js中:添加获取数据的接口

    export function getMusicList(topid) {
    const url = "https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.fcg" const data = Object.assign({}, commonParams, {
    page: 'detail',
    type: 'top',
    tpl: 3,
    platform: 'h5',
    needNewcode: 1
    }) return jsonp(url, data, options)
    }
  2. top-list.vue中:调用getMusicList()方法获取数据,在created()时获取
    import {getMusicList} from '@/api/rank'
    import {ERR_OK} from '@/api/config' created() {
    this._getMusicList()
    } getMusicList(this.topList.id).then((res) => {
    if(res.code === ERR_OK){
    this.songs = this._normalizeSongs(res.songlist)
    // console.log(res.songlist)
    }
    })
  3. 获得数据后,在methods中对数据进行一些处理:同歌单详情页,歌曲的播放url中的vkey需要发送请求获取,同时将处理好的数据封装新的Song实例
    import {getMusic} from '@/api/singer'
    import {createSong} from '@/common/js/song' _normalizeSongs(list) {
    let ret = []
    list.forEach((item) => {
    const musicData = item.data
    // console.log(musicData)
    if (musicData.songid && musicData.albumid) {
    getMusic(musicData.songmid).then((res) => {
    // console.log(res)
    if(res.code === ERR_OK){
    // console.log(res.data)
    const svkey = res.data.items
    const songVkey = svkey[0].vkey
    const newSong = createSong(musicData, songVkey)
    ret.push(newSong)
    }
    })
    }
    })
    return ret
    }

    这样数据就获取到了,剩下的把songs的数据传递给子组件就可以了

  • 把bgImage的图片换成榜单第一首歌的图片

    bgImage() {
    if (this.songs.length) {
    return this.songs[0].image
    }
    return this.topList.picUrl
    }

带排行的song-list组件的扩展和应用

  • 添加rank的DOM结构、图片以及样式
  • 添加props字段rank,默认false,设置只有当rank为true时排行显示
    rank: {
    type: Boolean,
    default: false
    }
    <div class="rank" v-show="rank">
  • 定义两个方法分别获得动态绑定的class和文案
    <span :class="getRankCls(index)">{{getRankText(index)}}</span>
    getRankCls(index) {
    if(index<=2) {
    return `icon icon${index}`
    }else{
    return 'text'
    }
    },
    getRankText(index) {
    if(index > 2) {
    return index + 1
    }
    }
  • music-list.vue作为中间组件,也需要扩展一个props字段rank
    rank: {
    type: Boolean,
    default: false
    }
  1. 传入<song-list>

    <song-list :rank="rank"></song-list>
  2. 这样就把最外层父组件传入的rank应用到了song-list.vue组件中
  3. top-list.vue中维护数据rank为true,同时传入<music-list>中

注:项目来自慕课网

【音乐App】—— Vue-music 项目学习笔记:歌单及排行榜开发的更多相关文章

  1. 【音乐App】—— Vue-music 项目学习笔记:歌手详情页开发

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star. 歌曲列表 歌曲播放 一.子 ...

  2. 【音乐App】—— Vue-music 项目学习笔记:用户个人中心开发

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star. 歌曲列表 收藏歌曲 一.用 ...

  3. 【音乐App】—— Vue-music 项目学习笔记:歌曲列表组件开发

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star. 当前歌曲播放列表 添加歌曲 ...

  4. 【音乐App】—— Vue-music 项目学习笔记:推荐页面开发

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 上一篇总结了项目概述.项目准备.页面骨架搭建.这一篇重点梳理推荐页面开发.项目github地址:https://github.com/66We ...

  5. 【音乐App】—— Vue-music 项目学习笔记:项目准备

    前言: 学习慕课网Vue高级实战课程后,在实践中总结一些这个项目带给自己的收获,希望可以再次巩固关于Vue开发的知识.这一篇主要梳理:项目概况.项目准备.页面骨架搭建.项目github地址:https ...

  6. 【音乐App】—— Vue-music 项目学习笔记:搜索页面开发

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star. 搜索歌手歌曲 搜索历史保存 ...

  7. 【音乐App】—— Vue-music 项目学习笔记:播放器内置组件开发(二)

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star. 播放模式切换 歌词滚动显示 ...

  8. 【音乐App】—— Vue-music 项目学习笔记:歌手页面开发

    前言:以下内容均为学习慕课网高级实战课程的实践爬坑笔记. 项目github地址:https://github.com/66Web/ljq_vue_music,欢迎Star. 一.歌手页面布局与设计 需 ...

  9. 最新 Vue 源码学习笔记

    最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...

随机推荐

  1. jsp运行机制

    一.JSP机制概述 可以把执行JSP页面的执行分成两个阶段,一个是转译阶段,一个是请求阶段. 转译阶段:JSP页面转换成Servlet类. 请求阶段:Servlet类执行,将响应结果发送至客户端. 1 ...

  2. 史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)

    ffmpeg.exe是大名鼎鼎的视频处理软件,以命令行参数形式运行.网上也有很多关于ffmpeg的资料介绍.但是在用C#做实际开发时,却遇到了几个问题及注意事项,比如如何无损处理视频?如何在转换格式的 ...

  3. 【.NET MVC分页】.NET MVC 使用pagelist 分页

    1.安装 2. 在NuGet程序包管理控制台 ,输入Install-Package PagedList.mvc 安装PagedList 和PageList.Mvc; 3. @{ Layout = nu ...

  4. activemq 简单聊天

    有兴趣加群qq:200634530

  5. springboot添加事务

    (转自:http://www.cnblogs.com/xingzc/p/6029483.html) 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合.由于数据 ...

  6. 【bzoj3555】[Ctsc2014]企鹅QQ 字符串hash

    题目描述 PenguinQQ是中国最大.最具影响力的SNS(Social Networking Services)网站,以实名制为基础,为用户提供日志.群.即时通讯.相册.集市等丰富强大的互联网功能体 ...

  7. BZOJ4823 [Cqoi2017]老C的方块 【最小割】

    题目 老C是个程序员. 作为一个懒惰的程序员,老C经常在电脑上玩方块游戏消磨时间.游戏被限定在一个由小方格排成的R行C列网格上,如果两个小方格有公共的边,就称它们是相邻的,而且有些相邻的小方格之间的公 ...

  8. Hibernate逆向工程生成代码

    编辑此文章,其目的是方便以后根据表生成相应的代码,然而并非所有的代码都是如此.这里的Hibernate 即响应题目的ssh框架中的“h”. 如图所示,点击右上角,在myeclipse之中.再点击Mye ...

  9. get****Context各个方法分析

    1 getApplicationContext分析 该方法为contextImpl类的方法,返回一个ApplicationContext.方法代码为: public Context getApplic ...

  10. CSS3 Flex布局和Grid布局

      1 flex容器的六个属性 flex实现垂直居中: <div class="box"> <span class="item">< ...