18143453325 在线咨询 在线咨询
18143453325 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > 【个人练习】网易云音乐PC端仿站 Vue 2(六)

【个人练习】网易云音乐PC端仿站 Vue 2(六)

时间:2023-04-21 13:57:01 | 来源:网站运营

时间:2023-04-21 13:57:01 来源:网站运营

【个人练习】网易云音乐PC端仿站 Vue 2(六):

目录

【个人练习】网易云音乐PC端仿站 Vue 2(一)

【个人练习】网易云音乐PC端仿站 Vue 2(二)

【个人练习】网易云音乐PC端仿站 Vue 2(三)

【个人练习】网易云音乐PC端仿站 Vue 2(四)

【个人练习】网易云音乐PC端仿站 Vue 2(五)

【个人练习】网易云音乐PC端仿站 Vue 2(六)

【个人练习】网易云音乐PC端仿站 Vue 2(七)

8 发现音乐页面

首页(发现音乐页面)包含一个导航栏,划分为“推荐”、“排行榜”、“歌单”、“主播电台”、“歌手”、“新碟上架”几个子栏目。

8-1 首页导航栏组件 HomeHeader

通过this.$route.path获取当前路由地址,判断当前选中的导航栏项目,赋予选中样式。

8-2 推荐

  1. 轮播图:
Banner
说明 : 调用此接口 , 可获取 banner( 轮播图 ) 数据
可选参数 :type:资源类型,对应以下类型,默认为 0 即 PC
0: pc, 1: android, 2: iphone, 3: ipad
接口地址 :/banner
使用变量imgIndex记录当前展示的图片索引,imgUrl记录当前展示图片的url。设置定时器,让轮播图自动播放。当鼠标移动到轮播图上,停止自动播放。底部小圆点,对应所有轮播图,点击小圆点,就展示对应的轮播图图片。左侧右侧两个箭头可以切换上一张和下一张图片。

<template> <div class="banner"> <div class="wrap-content"> <div class="banner-box"> <!-- 轮播图图片框 --> <div class="banner-frame" @mouseenter="stopPlay" @mouseleave="startPlay"> <!-- 图片 --> <div class="images"> <transition name="show"> <img v-lazy="imgUrl" v-show="isShow" /> </transition> </div> <!-- 底部小圆点 --> <ul class="points"> <li v-for="(point, index) in imgList" :key="index" :class="[imgIndex === index ? 'active' : '']" @click="changeImg(index)" ></li> </ul> <!-- 两侧箭头 --> <div class="prev-arrow" @click="prev"></div> <div class="next-arrow" @click="next"></div> </div> <!-- 下载 --> <div class="download"> <a href="javascript:;" class="download-btn"></a> <p>PC 安卓 iPhone WP iPad Mac 六大客户端</p> </div> </div> </div> <div class="img-blur"> <img v-lazy="imgUrl" class="blur" /> </div> </div></template><script>export default { name: 'Banner', data() { return { imgList: [], // 所有轮播图图片 imgUrl: '', // 轮播图当前展示的图片 imgIndex: 0, // 当前展示的图片在图片列表中的序号 autoPlay: true, // 是否自动播放轮播图 timer: null, // 定时器 isShow: true, } }, mounted() { // 获取轮播图图片 this.getBanner() // 启动轮播图自动播放定时器 this.startPlay() }, methods: { // 获取轮播图资源 async getBanner() { let result = await this.$api.reqBanner() result.banners.forEach((item) => { this.imgList.push({ id: item.targetId, url: item.imageUrl }) }) this.imgUrl = this.imgList[0].url }, // 切换图片 changeImg(index) { this.imgIndex = index this.imgUrl = this.imgList[index].url }, // 自动播放轮播图 startPlay() { this.timer = setInterval(() => { this.next() }, 4000) }, // 停止自动播放轮播图 stopPlay() { clearInterval(this.timer) }, // 切换上一张图片 prev() { this.imgIndex = (this.imgIndex > 0 ? this.imgIndex : this.imgList.length) - 1 this.imgUrl = this.imgList[this.imgIndex].url }, // 切换下一张图片 next() { this.imgIndex = (this.imgIndex + 1) % this.imgList.length this.imgUrl = this.imgList[this.imgIndex].url }, },}</script>2. 热门推荐、新碟上架、榜单数据通过接口获取。三个部分的标题部分结构和样式相似,可以提取出Title组件封装。新碟上架翻页功能的实现,通过设置列表相对于外部盒子的偏移实现。

歌单(网友精选碟)
说明 : 调用此接口 , 可获取网友精选碟歌单
可选参数 : order: 可选值为 'new' 和 'hot', 分别对应最新和最热 , 默认为 'hot'
cat: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 "全部",可从歌单分类接口获取(/playlist/catlist)
limit: 取出歌单数量 , 默认为 50
offset: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*50, 其中 50 为 limit 的值
接口地址 : /top/playlist

最新专辑
说明 : 调用此接口 ,获取云音乐首页新碟上架数据
接口地址 : /album/newest

所有榜单
说明 : 调用此接口,可获取所有榜单
接口地址 : /toplist
<script>export default { methods: { // 上一页 prevPage() { let albumlist = this.$refs.albumsList; if (this.page === 0) { albumlist.style.transition = 'none' albumlist.style.left = '-1290px' // 回到page2 this.page = 2 } this.timer = setTimeout(() => { albumlist.style.transition = 'left 1s' this.page -= 1 albumlist.style.left = -645 * this.page + 'px' }, 1100) }, // 下一页 nextPage() { let albumlist = this.$refs.albumsList; if (this.page === 2) { albumlist.style.transition = 'none' albumlist.style.left = '0px' this.page = 0 } this.timer = setTimeout(() => { albumlist.style.transition = 'left 1s' this.page += 1 albumlist.style.left = -645 * this.page + 'px' }, 1100) }, }}</script>3. 右侧入驻歌手和热门主播数据获取接口:

热门歌手
说明 : 调用此接口 , 可获取热门歌手数据
可选参数 : limit: 取出数量 , 默认为 50
offset: 偏移数量 , 用于分页 , 如 :( 页数 -1)*50, 其中 50 为 limit 的值 , 默认 为 0
接口地址 : /top/artists

获取歌手详情
说明 : 调用此接口 , 传入歌手 id, 可获得获取歌手详情
必选参数 : id: 歌手 id
接口地址 : /artist/detail

电台-最热主播榜
说明 : 调用此接口,可获取最热主播榜
可选参数 :
limit : 返回数量 , 默认为 100 (不支持 offset)
接口地址 : /dj/toplist/popular

8-3 排行榜

  1. 排行榜页面左侧是所有榜单的列表,右侧是榜单的详细内容,包含基本信息、歌曲列表以及评论。
  2. 点击左侧的榜单,右侧对应显示该榜单的详细内容,通过改变路由queryid实现。
// 榜单跳转goto(item) { this.$router.push({ path: '/home/toplist', query: { id: item.id, }, }) this.$bus.$emit('getFreq',item.updateFrequency) // 传递当前展示榜单的更新频率}3. 榜单的详细信息接口:

获取歌单详情
说明 : 歌单能看到歌单名字, 但看不到具体歌单内容 , 调用此接口 , 传入歌单 id, 可 以获取对应歌单内的所有的音乐(未登录状态只能获取不完整的歌单,登录后是完整的),但是返回的 trackIds 是完整的,tracks 则是不完整的,可拿全部 trackIds 请求一次 song/detail 接口获取所有歌曲的详情
必选参数 : id : 歌单 id
可选参数 : s : 歌单最近的 s 个收藏者,默认为 8
接口地址 : /playlist/detail
4. 由于获取到的歌曲列表信息不包含歌曲排名变化(也可能是没有找到T^T),使用以下代码生成模拟排名变化:

思路:给定歌曲列表中歌曲数num,当前的歌曲列表中的排列顺序即为当前的排名,生成1num序号的列表,随机打乱,作为之前的排名。同时,随机设置一些歌曲为新上榜歌曲。

// 打乱数组function shuffle(arr) { let newArr = [...arr] return newArr.sort(() => { let rand = Math.random() if (rand < 0.5) return -1 else return 1 })}// 模拟榜单排名变动 (num 有多少首歌)function rk_simulation(num) { let newRank = new Array(num) for (let i = 0; i < num; i++) { newRank[i] = i + 1; } let oldRank = shuffle(newRank) let change = new Array(num) for (let i = 0; i < num; i++) { let rand = Math.random() if (rand > 0.5) change[i] = oldRank[i] - newRank[i] else change[i] = num } return change}5. 评论获取接口:

歌单评论
说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该歌单的所有评论 ( 不需要 登录 )
必选参数 : id: 歌单 id
可选参数 : limit: 取出评论数量 , 默认为 20
offset: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*20, 其中 20 为 limit 的值
before: 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过 5000 条评论的时候需要用到)
接口地址 : /comment/playlist
6. 评论分页:将分页器单独封装成一个组件Pagination,通过props属性传递当前展示的页号pageNo、每页评论数pageSize、总评论数total、分页器连续展示的页数(不被省略号代替)continues,获取当前页数的函数getPageNo。当点击分页器中某一页时,调用getPageNo函数,使得父组件能够获取到请求的页号。

<template><div clas="comments"> <!-- 分页器 --> <Pagination :pageNo="pageNo" :pageSize="pageSize" :total="tolComments" :continues="5" @getPageNo="getPageNo"/></div></template><script>export default { // 获取当前页数 getPageNo(pageNo) { this.pageNo = pageNo this.getCommentsList() // 获取评论 }} </script>


<template> <div class="pagination"> <!-- 上一页 --> <button :disabled="pageNo===1" @click="$emit('getPageNo', pageNo - 1)" class="prev-page">上一页</button> <!-- 页码 --> <button v-if="startAndEndPage.start > 1" @click="$emit('getPageNo',1)" class="page">1</button> <span v-if="startAndEndPage.start > 2" class="point">...</span> <button class="page" v-for="(page, index) in parseInt(startAndEndPage.end)" :key="index" v-show="page >= startAndEndPage.start" :class="{active:isPage(page)}" @click="$emit('getPageNo',page)">{{page}}</button> <span v-if="startAndEndPage.end < tolPage-1" class="point">...</span> <button v-if="startAndEndPage.end < tolPage" @click="$emit('getPageNo',tolPage)" class="page">{{tolPage}}</button> <!-- 下一页 --> <button :disabled="pageNo===tolPage" @click="$emit('getPageNo', pageNo + 1)" class="next-page">下一页</button> </div></template><script>export default { name: 'Pagination', props: ['pageNo', 'pageSize', 'total', 'continues'], computed: { // 评论总页数 tolPage() { return Math.ceil(this.total / this.pageSize) }, // 展示按钮的起始和终止页序号 startAndEndPage() { let start = Math.max(1, this.pageNo - Math.floor(this.continues / 2)) let end = Math.min(this.tolPage, this.pageNo + Math.floor(this.continues / 2)) if (end - start < this.continues) { if (start === 1) { end = Math.min(Math.max(end, start + this.continues), this.tolPage) } else if (end === this.tolPage) { start = Math.max(1, Math.min(end - this.continues, start)) } } return { start, end } } }, methods: { // 判断是否是当前页面 isPage(page) { return page === this.pageNo } }}</script>

8-4 歌单

  1. 获取歌单分类接口:
歌单分类
说明 : 调用此接口,可获取歌单分类,包含 category 信息
接口地址 : /playlist/catlist
2. 使用变量category记录当前展示的歌单的类别,从而在切换歌单分类时,按照分类获取歌单列表。

8-5 主播电台

  1. 通过获取路由queryid,判断当前是主播电台推荐页面(没有id,即id为undefined)还是某种电台分类的详情页面(id为电台类别号),在切换电台分类时,也是通过修改路由queryid跳转页面。
  2. 接口:
电台-分类
说明 : 登录后调用此接口 , 可获得电台类型
接口地址 : /dj/catelist

推荐节目
说明 : 调用此接口 , 可获取推荐电台
接口地址 : /program/recommend

电台-节目榜
说明 : 登录后调用此接口 , 可获得电台节目榜
可选参数 :
limit : 返回数量 , 默认为 100
offset : 偏移数量,用于分页 , 如 :( 页数 -1)*100, 其中 100 为 limit 的值 , 默认为 0
接口地址 : /dj/program/toplist

电台-分类推荐
说明 : 登录后调用此接口 , 传入分类,可获得对应类型电台列表
必选参数 : type: 电台类型 , 数字 , 可通过/dj/catelist获取 , 对应关系为 id 对应 此接口的 type, name 对应类型
接口地址 : /dj/recommend/type

电台-类别热门电台
可选参数 :
limit : 返回数量 , 默认为 30
offset : 偏移数量,用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认为 0
cateId: 类别 id,可通过 /dj/category/recommend 接口获取
接口地址 : /dj/radio/hot

8-6 歌手

  1. 路由query中包含areatypearea表示歌手区域分类(华语、欧美、日本、韩国、其他),都有对应的编号;type表示歌手的类型(男歌手、女歌手、组合/乐队)。当areatype均为undefined时,展示的是推荐歌手,当areatype均为-1时,展示的是入驻歌手。
  2. 具体歌手分类页面中可以根据字母索引查找歌手,只需要将选择的字母索引作为参数传递到查询接口即可。
歌手分类列表
说明 : 调用此接口,可获取歌手分类列表
可选参数 :
limit : 返回数量 , 默认为 30
offset : 偏移数量,用于分页 , 如 : 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认为 0 initial: 按首字母索引查找参数,如 /artist/list?type=1&area=96&initial=b 返回内容将以 name 字段开头为 b 或者拼音开头为 b 为顺序排列, 热门传-1,#传 0
type 取值:
-1:全部
1:男歌手
2:女歌手
3:乐队
area 取值:
-1:全部
7:华语
96:欧美
8:日本
16:韩国
0:其他
接口地址 :/artist/list

8-7 新碟上架

全部新碟
说明 : 登录后调用此接口 ,可获取全部新碟
可选参数 :
limit : 返回数量 , 默认为 30
offset : 偏移数量,用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认为 0
area: ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本
接口地址 : /album/new

关键词:音乐,练习

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭