这篇文章主要为大家详细介绍了vue-music关于player播放器组件的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了关于player播放器组件的具体内容,供大家参考,具体内容如下
迷你播放器:
1.播放器组件会在各个页面的情况下会打开。 首先在vuex state.js 中定义全局的播放器状态
import {playmode} from 'common/js/config.js';const state = { singer:{}, playing:false, //是否播放 fullscreen:false, //是否全屏 playlist:[], //播放列表 sequencelist:[], // 非顺序播放列表 mode:playmode.sequence, // 播放模式(顺序0,循环1,随机2) currentindex:-1, //当前播放索引}export default state ---------------------------------------------// config.jsexport const playmode = { sequence:0, loop:1, random:2}
2.进入播放器页面时获取播放列表数据,改变播放状态 在music-list列表中打开
在song-list 组件中派发事件到父组件,传入当前歌曲的信息和索引
<li @click="selectitem(song,index)" v-for="(song,index) in songs" class="item">------------------------------selectitem(item,index){ this.$emit('select',item,index)},
在music-list 组件中接受派发事件。
<song-list :rank="rank" :songs="songs" @select="selectitem"></song-list>
3. 如果commit 多个状态在actions 里设置
import {playmode} from 'common/js/config.js'export const selectplay = function({commit,state},{list,index}){ commit(types.set_sequence_list, list) commit(types.set_playlist, list) commit(types.set_current_index, index) commit(types.set_full_screen, true) commit(types.set_playing_state, true)}
4. 在music-list 组件中 用mapactions提交 改变值
import {mapactions} from 'vuex'methods:{ selectitem(item,index){ this.selectplay({ list:this.songs, index }) }, ...mapactions([ 'selectplay' ]) },
5.在palyer 中获取vuex 全局状态,赋值状态到相应位置(代码为完整代码,对照后面讲解慢慢理解)
<p class="player" v-show="playlist.length>0">// 如果有列表数据则显示 <p class="normal-player" v-show="fullscreen">//如果全屏 <p class="background"> <img :src="currentsong.image" alt="" width="100%" height="100%">//模糊背景图 </p> <p class="top"> <p class="back" @click="back"> <i class="icon-back"></i> </p> <h1 class="title" v-html="currentsong.name"></h1>//当前歌曲名称 <h2 class="subtitle" v-html="currentsong.singer"></h2>//当前歌手名 </p> <p class="middle"> <p class="middle-l"> <p class="cd-wrapper"> <p class="cd" :class="cdcls"> <img :src="currentsong.image" alt="" class="image">//封面图 </p> </p> </p> </p> <p class="bottom"> <p class="progress-wrapper"> <span class="time time-l">{{ format(currenttime) }}</span> <p class="progress-bar-wrapper"> <progress-bar :percent="percent" @percentchange="onprogressbarchange"></progress-bar> </p> <span class="time time-r">{{ format(currentsong.duration) }}</span> </p> <p class="operators"> <p class="icon i-left"> <i :class="iconmode" @click="changemode"></i> </p> <p class="icon i-left" :class="disablecls"> <i @click="prev" class="icon-prev"></i> </p> <p class="icon i-center" :class="disablecls"> <i :class="playicon" @click="toggleplaying"></i> </p> <p class="icon i-right" :class="disablecls"> <i @click="next" class="icon-next"></i> </p> <p class="icon i-right"> <i class="icon icon-not-favorite"></i> </p> </p> </p> </p> </transition> <transition name="mini"> <p class="mini-player" v-show="!fullscreen" @click="open"> <p class="icon"> <img :src="currentsong.image" alt="" width="40" height="40" :class="cdcls"> </p> <p class="text"> <h2 class="name" v-html="currentsong.name"></h2> <p class="desc" v-html="currentsong.singer"></p> </p> <p class="control"> <i :class="miniicon" @click.stop="toggleplaying"></i> </p> <p class="control"> <i class="icon-playlist"></i> </p> </p> </transition> <audio :src="currentsong.url" ref="audio" @canplay="ready" @error="error" @timeupdate="updatetime" @ended="end"></audio> </p>
打开播放器的状态
import {mapgetters,mapmutations} from 'vuex';...mapgetters([ 'fullscreen', 'playlist', 'currentsong', 'playing', 'currentindex',])
注意:不可在组件中直接赋值改版vuex 中的状态 this.fullscreen = false 需要通过mutations 改变,定义mutation-types 和mutations 然后 用vuex的 mapmutations 代理方法调用
[types.set_full_screen](state, flag) { state.fullscreen = flag },import {mapgetters,mapmutations} from 'vuex';methods:{ ...mapmutations({ setfullscreen:"set_full_screen", }), back(){ this.setfullscreen(false) },}
设置点击播放按钮方法
<i :class="playicon" @click="toggleplaying"></i>
toggleplaying(){ this.setplayingstate(!this.playing); //改变全局变量playing 的属性},// 然后watch 监听playing 操作实际的audio 标签的播放暂停watch:{ playing(newplaying){ let audio = this.$refs.audio; this.$nexttick(() => { newplaying ? audio.play():audio.pause(); }) } },// 用计算属性改变相应的播放暂停图标playicon(){ return this.playing? 'icon-pause':'icon-play'},
设置点击播放上一首和下一首按钮方法。用mapgetters 获取currentindex 的值(加一或减一) 并改变,从而改变 currentsong 的状态,监听切换播放。判断播放列表界限重置。
prev(){if(!this.songready){return;} let index = this.currentindex - 1; if(index === -1){//判断播放列表界限重置 index = this.playlist.length-1; } this.setcurrentindex(index); if(!this.playing){//判断是否播放改变播放暂停的icon this.toggleplaying(); } this.songready = false;},next(){ if(!this.songready){return; } let index = this.currentindex + 1; if(index === this.playlist.length){//判断播放列表界限重置 index = 0; } this.setcurrentindex(index); if(!this.playing){ this.toggleplaying(); } this.songready = false;},
监听audio 元素标签的canpaly 事件,当歌曲加载就绪 和 error 事件,当歌曲发生错误的时候,做用户体验,防止用户快速切换导致报错。
设置songready 标志位 如果歌曲没有准备就绪,点击下一首的时候直接return false
data(){ return { songready:false, }},ready(){ this.songready = true;},error(){ this.songready = true;},
进度条
audio元素监听 timeupdate 事件获取当前播放时间的 可读写属性 时间戳。用formt做格式化时间处理,(_pad 为补零函数 )
获取音频总时长 currentsong.duration
<p class="progress-wrapper"> <span class="time time-l">{{ format(currenttime) }}</span> <p class="progress-bar-wrapper"> <progress-bar :percent="percent" @percentchange="onprogressbarchange"></progress-bar> </p> <span class="time time-r">{{ format(currentsong.duration) }}</span></p><audio :src="currentsong.url" ref="audio" @canplay="ready" @error="error" @timeupdate="updatetime" @ended="end"></audio>
updatetime(e){ this.currenttime = e.target.currenttime; // 获取当前播放时间段},format(interval){ interval = interval | 0; const minute = interval/60 | 0; const second = this._pad(interval % 60); return `${minute}:${second}`; },_pad(num,n=2){ let len = num.tostring().length; while(len<n){ num = '0' + num; len ++; } return num;},
建立progress-bar 组件 接收pencent 进度参数,设置进度条宽度和小球的位置。player组件 设置计算属性percent
percent(){ return this.currenttime / this.currentsong.duration // 当前时长除以总时长},
progress-bar 组件
<p class="progress-bar" ref="progressbar" @click="progressclick"> <p class="bar-inner"> <p class="progress" ref="progress"></p> <p class="progress-btn-wrapper" ref="progressbtn" @touchstart.prevent="progresstouchstart" @touchmove.prevent="progresstouchmove" @touchend="progresstouchend" > <p class="progress-btn"></p> </p> </p> </p>
const progressbtnwidth = 16 //小球宽度props:{ percent:{ type:number, default:0 }},watch:{ percent(newpercent){ if(newpercent>=0 && !this.touch.initated){ const barwidth = this.$refs.progressbar.clientwidth - progressbtnwidth; const offsetwidth = newpercent * barwidth; this.$refs.progress.style.width = `${offsetwidth}px`; this.$refs.progressbtn.style.transform=`translate3d(${offsetwidth}px,0,0)` } }}
设置拖动
在进度条小按钮progressbtn 上添加touchstart,touchmove,touchend 事件监听方法,事件添加 prevent 防止拖动默认浏览器行为,获取拖动的信息进行计算
在实例上创建一个touch 对象维护不同的回调之间的通讯共享状态信息。 touchstart事件方法中 ,首先设置this.touch.initated为true,表示拖动开始。 记录开始点击位置 e.touches[0].pagex 存到 touch 对象上,记录当前的进度宽度。
在touchmove 中首先判断 是否先进入了 touchstart 方法,计算得到 移动的位置 减去 点击开始的位置的 偏移量长度。 let deltax = e.touches[0].pagex - this.touch.startx
就可以 设置进度条 已有的长度加上偏移量长度。最大不能超过父级progressbar 的宽度
调用this._offset(offsetwidth) 方法设置进度条宽度
在touchend 事件方法中将 this.touch.initated 设置为false,表示拖动结束,并派发事件到player 组件将audio的currenttime 值设置为正确值,参数为pencent
在progressbar 中增加点击事件,调用this._offset(e.offsetx),并且派发事件
created(){ this.touch = {}; },methods:{ progresstouchstart(e){ this.touch.initiated = true; this.touch.startx = e.touches[0].pagex; this.touch.left = this.$refs.progress.clientwidth; }, progresstouchmove(e){ if(!this.touch.initiated){ return; } let deltax = e.touches[0].pagex - this.touch.startx; let offsetwidth = math.min(this.$refs.progressbar.clientwidth - progressbtnwidth,math.max(0,this.touch.left + deltax)); this._offset(offsetwidth); }, progresstouchend(e){ this.touch.initiated = false; this._triggerpercent(); }, progressclick(e){ const rect = this.$refs.progressbar.getboundingclientrect(); const offsetwidth = e.pagex - rect.left; this._offset(offsetwidth); // this._offset(e.offsetx); this._triggerpercent(); }, _offset(offsetwidth){ this.$refs.progress.style.width = `${offsetwidth}px`; this.$refs.progressbtn.style[transform] = `translate3d(${offsetwidth}px,0,0)`; }, _triggerpercent(){ const barwidth = this.$refs.progressbar.clientwidth - progressbtnwidth; const percent = this.$refs.progress.clientwidth / barwidth; this.$emit("percentchange",percent) }},
本文已被整理到了《vue.js前端组件学习教程》,欢迎大家学习阅读。
关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。
更多vue学习教程请阅读专题《vue实战教程》
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
在vue.js中如何整合mint-ui里的轮播图
在jstree中如何实现选中父节点时被禁用的子节点也会选中
在vue中关于过滤器filters的用法
在javascript中自适应处理方法
以上就是在vue-music中关于player播放器组件的使用说明的详细内容。
