项目介绍
功能 | 描述 |
---|---|
首页推荐 | 首页顶部为轮播图下方内容区域为歌单推荐部分 |
歌手 | 包括各种分类歌手乐队可以选择 |
歌单详情 | 各个歌单在点击后进入歌单详情页面 |
rank榜 | 各类排行榜 |
主题换肤 | 供喜欢样式选择 |
搜索 | 根据歌曲/歌手相关信息进行搜索 |
歌曲播放模式 | 顺序播放、单曲循环、随机播放 |
关于 | 相关版本信息 |
项目地址
https://github.com/Mr-programming/vue_music
原项目地址
项目思路
主界面分为 recommend首页推荐 ,singer歌手选择,rank排行榜,搜索界面,歌单详情,播放界面
关于路由跳转采用路由懒加载的形式,图片展示采用v-lazy属性,路由跳转完毕页面等待加载时展示loading组件(展示一个gif动态图)
首页推荐
首页推荐和歌手选择以及rank榜模块的整体思路类似,在created钩子中就执行加载资源函数,再将歌单对象数组中的各个歌单对象展示到相应位置,包括图片名称。
子路由模块
这里给每一个组件(首页推荐和歌手选择以及rank榜)都添加子路由,在点击对应的歌单对象后都会执行两个函数,第一个向vuex中传入歌单对象,第二个函数跳转路由。子组件此时会从vuex中拿到对象同时根据歌单id请求歌曲列表
每个子路由组件中都会有一对公用的父子组件来展示歌单详情列表,这里子路由组件只起到请求资源的作用,它会把通过歌单对象请求的歌单信息和歌曲列表传递给这对父子组件,其中父组件展示歌单图片和名字,子组件展歌曲列表
搜索模块
关于搜索模块,内部嵌套两个子组件,一个是搜索框区域search-box,一个是搜索结果区域suggest,在搜索模块本身created钩子中加载热门搜索关键字,一旦搜索区域有内容输入关键字部分则会隐藏。
在search-box组件中会绑定自定义事件 ,该组件会监听输入内容然后触发自定义事件,从而父组件搜索模块会拿到输入结果,这里触发自定义函数外包裹了节流函数,防止监听到输入一个字符就立马触发自定义事件函数
在搜索模块拿到搜索区域的内容时 会把这个字符串传递给suggest去请求搜索结果并展示
播放模块
关于播放歌曲组件player ,可以控制是否全屏(默认为全屏),在通过歌单详情列表点击某个歌曲时,会把这个歌曲列表和被点击歌曲的索引值传到vuex中,歌曲列表传到顺序列表和播放列表(顺序列表是原封不动的传递,播放列表会根据当前已选择的播放模式来判断是否洗牌),player组件是根据播放列表中是否有内容来展示的,播放器播放的歌曲是通过mapGetters拿到当前播放列表数组中指定索引的歌曲对象。在搜索歌曲中 点歌曲会往播放列表和顺序列表中插队,索引重新指向当前点击歌曲。
当前播放列表
在播放组件全屏时候可以展示当前播放列表,每一个歌曲都可以从播放列表删除
关于切换歌曲
关于切换歌曲,切换歌曲只需改变播放列表索引值即可。
关于切换模式
关于切换模式,切换模式有三种:0(顺序播放)、1(单曲循环)、2(随机播放) 。在点击顺序播放时会把原本的顺序列表赋给播放列表(当前播放歌曲索引要重新搜索确保,确保当前播放的歌曲是不变的),随机播放是把当前播放列表洗牌,后续同上。
关于主题换肤
关于主题换肤theme:同样是0,1,2三种 默认为0,在选择之后所有相关页面都会改变颜色(通过vuex)
vuex 中的state
const state = {
theme: 0, //主题颜色 默认值为0
disc: {}, //歌单对象
singer: {}, //歌手对象(和歌单对象类似)
rank: {}, //榜单对象(同上)
sequenceList: [], //顺序列表
playList: [], //当前播放列表
mode: 0, //播放模式(默认0顺序播放 1单曲 2随机)
playing: false, //播放状态
fullScreen: false, //是否全屏
currentIndex: -1, //当前播放歌曲的索引,
}
export default state;
App根组件的模板
<template>
<div >
<div class="App_Top">
<Mhead/>
<Tab/>
</div>
<div class="AppContent">
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
<div class="bottom">
<player/>
</div>
</div>
</template>
洗牌函数
//洗牌函数的辅助函数
function getRandomInt(min, max) {
//floor为向下取整
return Math.floor(Math.random() * (max - min + 1) + min);
}
//洗牌函数,打乱歌曲顺序
export function shuffle(arr) {
let _arr = arr.slice();
//保留arr,制作一个副本
for (let i = 0; i < _arr.length; i++) {
let j = getRandomInt(0, i);
let temp = _arr[i];
_arr[i] = _arr[j];
_arr[j] = temp;
}
return _arr;
}
节流函数
//截流函数 防止输入一个字符就去请求
export function debounce(func, delay) {
let timer;
return function(...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}