Vue+Vuex+Element-ui实现歌曲播放控件、播放列表功能
写在前⾯:
根据思路写代码和写⽂章的区别还是挺⼤的,后者更多需要的是⼀个总结表述的能⼒,以及需要判断⽂章中呈现的东西是否有价值。做笔记和写博客同样是在记录,⽽博客还承担了⼀个供别⼈浏览的职能,所以如何把⾃⼰的逻辑表达得让⼤众都能理解,也是⼀个值得研究的地⽅。
由于个⼈技术的影响,⽂章中可能会出现⼀些错误,⼩到格式排版,⼤到逻辑错误都正常,所以写博客的原因主要是:
1. 帮助重新梳理⾃⼰的逻辑,记录⾃⼰的学习过程
2. 希望能与更多伙伴进⾏技术上的交流,如果还能⼤佬指出问题或提⼀些建议,那就是赚到
3. 如果还能帮到⼀些可能会遇到此类问题的⼩伙伴,那也是极好的
废话有点多,开始进⼊主题叭
——————(平平⽆奇的分割线) ——————
这⼀篇主要更新的是播放控制组件,以及播放列表这部分的实现,因为还涉及到组件之间的⼀些通信,所以在这之前可以先看⼀下我的上⼀篇博客:
两篇结合起来可以实现⼀个简单但是基本功能都完善的⾳乐播放器功能了
这⾥可以直接移步 ,轻轻点个Star,开⼼你我他!skr~
请在PC端查看噢!
再次进⼊主题。。。
——————(平平⽆奇的分割线) ——————
播放控制组件
同样的,先上⼀下效果图
可以看到这⾥主要分为两个部分,⼀个是放置歌曲进度条、控制歌曲播放顺序等,⼀个就是当前播放列表了。
1、引⼊vuex
在这之前,我们先来看看我们的store⾥需要管理的内容。
刚刚已经说过,播放控制组件与歌曲信息组件是需要数据的交互的,如
所以我们创建⼀个store来对它们需要同步的信息进⾏管理,我们在项⽬的src⽂件夹下新建⼀个vuex⽂件夹,并在⾥⾯新建个store.js⽂件,我们之后就在这个⽂件⾥写状态管理的代码了。
1. 下载vuex : npm install vuex --save
2. 在store.js⾥添加下⾯内容,刚⼊门的⼩伙伴可以和我⼀样使⽤下⾯这个模板,这样的格式看起来会⽐较清晰。
这⾥推荐⼀个⽂章
import Vue from'vue'
import Vuex from'vuex'
Vue.use(Vuex)
const state ={
}
const getters ={
网页版音乐播放器}
const mutations ={
}
const actions ={
}
export default new Vuex.Store({
state,
getters,
mutations,
actions
})
我们这⾥主要⽤到的属性就state和mutations。
state就是Vuex中的公共的状态, 相当于我们组件⾥的data属性,⽤于保存所有组件的公共数据,下⾯就来看看我们需要的公共数据
const state ={
playList:[],//播放列表
playContent:{},//当前播放的歌曲信息
current:""//当前歌曲的播放进度
}
播放列表:在歌曲列表中点击播放或者添加时,就更新播放列表,⽽播放控制部分的循环模式也是需要通过播放列表来实现的播放信息:不管是在歌词页⾯还是播放控制组件上都需要进⾏展⽰
播放进度:控制歌词滚动以及播放进度条的更新
接下来我们需要⽤到mutaions属性,它相当于我们组件中的methods,当我们在这⾥可以处理组件提交的事件,然后对state的值进⾏⼀个更新修改。
const mutations ={
//获取当前播放歌曲的信息
setContent(state, payload){
state.playContent = payload
state.playList.indexOf(payload)==-1?state.playList.push(payload):""
},
//获取当前播放歌曲的歌词
setLyric(state, payload){
state.playContent.lyric = payload
},
//设置当前播放歌曲的进度
setCurrent(state, payload){
state.current = il(payload)
},
//从播放列表中移除歌曲
removeSong(state, payload){
let index = state.playList.indexOf(payload)
state.playList.splice(index,1)
},
//往播放列表中加⼊歌曲
addSong(state, payload){
let index = state.playList.indexOf(payload)
state.playList.indexOf(payload)==-1?state.playList.push(payload):""
}
}
到这⾥,我们对store的设置已经结束,下⾯就回到播放控制组件的实现上
2、播放控制
为了能在不同页⾯下都能够控制歌曲的播放,我将该组件挂载在根组件下,并设置fixed定位把它固定在底部,如果担⼼影响其他内容的浏览,可以给它设置个透明度,⽤到的时候在通过个hover把它显⽰出来就好了。
(1)data
下⾯看⼀下我们组件需要的数据
data(){
return{
playStatus:false,//播放状态,⽤来控制播放、暂停按钮的显⽰
Timer:"",//定时器,我们需要实时监听到歌曲的播放进度
currentBar:0,//进度条长度,默认为0,根据歌曲进度同步更新
currentText:"00:00",//进度条旁边的播放时间,同样要实时更新
durationText:"00:00",//当前歌曲的播放时长
listShow:false,//控制播放列表的显⽰
loopStyle:"list"//not:单曲播放 list:列表循环 single:单曲循环 random:随机循环
};
}
//从store中获取
computed:{
//当前播放信息
songContent(){
return this.$store.state.playContent;
},
//播放列表信息
playList(){
return this.$store.state.playList;
}
}
如果直接获取store中的数据时,当state改变时,组件是不会同步更新的,所以我们需要把他们放到computed属性下,这样当数据有变化时,computed下的函数会重新执⾏,从⽽达到实时更新的效果。
然后我们再⽤watch对播放信息进⾏⼀个监听,当他发⽣改变的时候,说明需要进⾏⼀个重新播放功能
watch:{
songContent(){
this.playSong(this.songContent);//传⼊当前播放歌曲对象
}
}
对数据的监听获取部分已经完成,接下来我们开始在methods⾥进⾏功能函数的实现
(1) 初始化播放信息
对播放控件上的信息进⾏⼀个初始化渲染
//初始化播放歌曲
playSong(obj){
this.durationText = obj.dt;
this.playStatus =true;
this.currentText ="00:00";
this.currentBar =0;
let song_url ="api.imjad/cloudmusic/?type=song&id="+ obj.id;
}
/
/获取歌曲资源并播放
getSong(url){
this.$axios
.get(url)
.then(
res =>(
(this.$refs.audio.src = res.data.data[0].url),this.setTimer()//设置定时器
)
)
.catch(function(err){
console.log(err);
});
}
然后我们在audio标签⾥设置autoplay,当src改变时就会⾃动播放
<audio ref="audio"autoplay></audio>
(2) 更新进度条
开始播放后我们需要设置⼀个定时器,⽤以更新进度条
//设置定时器
setTimer(){
this.clearTimer();//先清除上⼀个定时器
this.Timer =setInterval(this.updateCurrent,1000);
},
/
/清除定时器
clearTimer(){
clearInterval(this.Timer);
this.Timer ="";
}
三元表达式⽤上瘾了…
还是简单解释⼀下吧
进度条⽤的是element-ui的<el-slider>标签,进度值0-100
<el-slider v-model="currentBar":show-tooltip="false"@click.native="skipBar"></el-slider>
当进度条等于100时,也就是歌曲播放结束时,进⾏循环⽅式的判断,然后按照当前循环⽅式进⾏相应的歌曲切换。如果歌曲还在播放中,就通过this.$refs.audio.currentTime获取播放进度,最后还要更新store⾥的播放进度。
//更新进度条
updateCurrent(){
this.currentBar ==100
?(this.clearTimer(),this.loopStyle =="not"
?Loop()
:this.loopStyle =="list"
?this.listLoop()
:this.loopStyle =="single"
?this.singleLoop()
:this.randomLoop()
)
:
(this.currentBar =
(this.$refs.audio.currentTime /this.$refs.audio.duration)*100),
(this.currentText =this.formatTime(this.$refs.audio.currentTime)),//formatTime()是对播放时间进⾏⼀个格式化
this.$storemit("setCurrent",this.$refs.audio.currentTime);
}
//格式化播放时间
formatTime(string){
var m =parseInt(string /60);
var s =parseInt(string %60);
m >=10? m :(m ="0"+ m);
s >=10? s :(s ="0"+ s);
return m +":"+ s;
}
(3) 不同的播放⽅式
在播放控制组件内还有个播放暂停功能,播放列表上也会有切换歌曲播放的按钮,这⼏种播放的前置条件都不完全相同,所以需要有分别对应的函数。
//点击播放
play(){
this.$ded //先判断歌曲是否播放完成了,如果是则重新播放,否则继续
?this.playSong(this.songContent)
:this.$refs.audio.play(),
this.setTimer();
this.playStatus =true;//改变播放状态主要是为了隐藏播放按钮
},
//点击暂停
pause(){
this.playStatus =false;
this.$refs.audio.pause(),this.clearTimer();//暂停时需要清除计时器,直到下次播放
}
//在列表上点击播放歌曲
cutSong(obj){
obj ==this.songContent
?this.play()
:this.$storemit("setContent", obj);
}
(4) 切换歌曲
歌曲的循环⽅式有单曲播放、列表循环、单曲循环、以及随机播放,所以我们要在歌曲完成后判断是否切换下⼀⾸,以及如何切换下⼀⾸。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论