VUE移动端音乐APP学习【十一】:播放歌曲前进后退功能实现
给前进和后退图标分别添加点击事件
<div class="icon i-left"> <i @click="prev" class="iconfont icon-prev"></i> </div> <div class="icon i-right"> <i @click="next" class="iconfont icon-next"></i> </div>
定义事件:
next() { // 如果没有ready好的话就直接返回 if (!this.songReady) { return; } // 因为是下一首歌,当前索引+1 let index = this.currentIndex + 1; if (index === this.playlist.length) { index = 0; } this.setCurrentIndex(index); if (!this.playing) { this.togglePlaying(); } this.songReady = false; }, prev() { // 如果没有ready好的话就直接返回 不能使用下面的逻辑实现功能 if (!this.songReady) { return; } let index = this.currentIndex - 1; if (index === -1) { index = this.playlist.length - 1; } this.setCurrentIndex(index); if (!this.playing) { this.togglePlaying(); } this.songReady = false; },
注意:
①因为要修改currentIndex 需要在mapGetters映射一下currentIndex,也要在mapMutations映射一下 setCurrentIndex方法 就可以调用这个方法修改index
②当我们在暂停状态下点击下一首发现 下一首歌在播放但是图标却是播放图标(即歌曲为停止状态),这里就还需要添加一个逻辑 如果发现playing状态为false时,即在暂停的情况切歌,就调用togglePlaying 去改变playing状态
当快速切歌时发现会有一定概率触发之前遇到的DOMException,去查阅相关文档发现有2个事件:@canplay和@error
① @canplay="ready" 歌曲可以播放的时候派发一个事件canplay
② 当我们歌曲发生错误,请求不到地址的时候会派发一个error
我们不希望可以连续点击下一首歌,只有当我们的歌曲ready的时候才能点下一首歌,用一个标志位songready来控制
<audio ref="audio" :src="currentSong.url" @canplay="ready" @error="error"></audio> data() { return { songReady: false, }; }, togglePlaying() { // 如果没有ready好的话就直接返回 if (!this.songReady) { return; } this.setPlayingState(!this.playing); }, ready() { this.songReady = true; }, error() { this.songReady = true; },
两个事件(歌曲OK 和歌曲加载失败)都设置为true 既不会影响我们正常的使用,又能避免快速点击操作导致的报错
最后做一个优化:如果不能点击的时候,添加一个disable的class
<div class="icon i-left" :class="disableCls"> <i @click="prev" class="iconfont icon-prev"></i> </div> <div class="icon i-center" :class="disableCls"> <i @click="togglePlaying" class="iconfont" :class="playIcon"></i> </div> <div class="icon i-right" :class="disableCls"> <i @click="next" class="iconfont icon-next"></i> </div>
disableCls() { return this.songReady ? '' : 'disable'; },