当前位置:Gxlcms > JavaScript > 在vue-music中关于Player播放器组件的使用说明

在vue-music中关于Player播放器组件的使用说明

时间:2021-07-01 10:21:17 帮助过:18人阅读

这篇文章主要为大家详细介绍了vue-music关于Player播放器组件的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了关于Player播放器组件的具体内容,供大家参考,具体内容如下

迷你播放器:

1.播放器组件会在各个页面的情况下会打开。 首先在vuex state.js 中定义全局的播放器状态

  1. import {playMode} from 'common/js/config.js';
  2. const state = {
  3. singer:{},
  4. playing:false, //是否播放
  5. fullScreen:false, //是否全屏
  6. playList:[], //播放列表
  7. sequenceList:[], // 非顺序播放列表
  8. mode:playMode.sequence, // 播放模式(顺序0,循环1,随机2)
  9. currentIndex:-1, //当前播放索引
  10. }
  11. export default state
  12. ---------------------------------------------
  13. // config.js
  14. export const playMode = {
  15. sequence:0,
  16. loop:1,
  17. random:2
  18. }

2.进入播放器页面时获取播放列表数据,改变播放状态 在music-list列表中打开

在song-list 组件中派发事件到父组件,传入当前歌曲的信息和索引

  1. <li @click="selectItem(song,index)" v-for="(song,index) in songs" class="item">
  2. ------------------------------
  3. selectItem(item,index){
  4. this.$emit('select',item,index)
  5. },

在music-list 组件中接受派发事件。

  1. <song-list :rank="rank" :songs="songs" @select="selectItem"></song-list>

3. 如果commit 多个状态在actions 里设置

  1. import {playMode} from 'common/js/config.js'
  2. export const selectPlay = function({commit,state},{list,index}){
  3. commit(types.SET_SEQUENCE_LIST, list)
  4. commit(types.SET_PLAYLIST, list)
  5. commit(types.SET_CURRENT_INDEX, index)
  6. commit(types.SET_FULL_SCREEN, true)
  7. commit(types.SET_PLAYING_STATE, true)
  8. }

4. 在music-list 组件中 用mapActions提交 改变值

  1. import {mapActions} from 'vuex'
  2. methods:{
  3. selectItem(item,index){
  4. this.selectPlay({
  5. list:this.songs,
  6. index
  7. })
  8. },
  9. ...mapActions([
  10. 'selectPlay'
  11. ])
  12. },

5.在palyer 中获取vuex 全局状态,赋值状态到相应位置(代码为完整代码,对照后面讲解慢慢理解)

  1. <p class="player" v-show="playList.length>0">    // 如果有列表数据则显示
  2. <p class="normal-player" v-show="fullScreen">  //如果全屏
  3. <p class="background">
  4. <img :src="currentSong.image" alt="" width="100%" height="100%">    //模糊背景图
  5. </p>
  6. <p class="top">
  7. <p class="back" @click="back">
  8. <i class="icon-back"></i>
  9. </p>
  10. <h1 class="title" v-html="currentSong.name"></h1>    //当前歌曲名称
  11. <h2 class="subtitle" v-html="currentSong.singer"></h2>  //当前歌手名
  12. </p>
  13. <p class="middle">
  14. <p class="middle-l">
  15. <p class="cd-wrapper">
  16. <p class="cd" :class="cdCls">
  17. <img :src="currentSong.image" alt="" class="image">    //封面图
  18. </p>
  19. </p>
  20. </p>
  21. </p>
  22. <p class="bottom">
  23. <p class="progress-wrapper">
  24. <span class="time time-l">{{ format(currentTime) }}</span>
  25. <p class="progress-bar-wrapper">
  26. <progress-bar :percent="percent" @percentChange="onProgressBarChange"></progress-bar>
  27. </p>
  28. <span class="time time-r">{{ format(currentSong.duration) }}</span>
  29. </p>
  30. <p class="operators">
  31. <p class="icon i-left">
  32. <i :class="iconMode" @click="changeMode"></i>
  33. </p>
  34. <p class="icon i-left" :class="disableCls">
  35. <i @click="prev" class="icon-prev"></i>
  36. </p>
  37. <p class="icon i-center" :class="disableCls">
  38. <i :class="playIcon" @click="togglePlaying"></i>
  39. </p>
  40. <p class="icon i-right" :class="disableCls">
  41. <i @click="next" class="icon-next"></i>
  42. </p>
  43. <p class="icon i-right">
  44. <i class="icon icon-not-favorite"></i>
  45. </p>
  46. </p>
  47. </p>
  48. </p>
  49. </transition>
  50. <transition name="mini">
  51. <p class="mini-player" v-show="!fullScreen" @click="open">
  52. <p class="icon">
  53. <img :src="currentSong.image" alt="" width="40" height="40" :class="cdCls">
  54. </p>
  55. <p class="text">
  56. <h2 class="name" v-html="currentSong.name"></h2>
  57. <p class="desc" v-html="currentSong.singer"></p>
  58. </p>
  59. <p class="control">
  60. <i :class="miniIcon" @click.stop="togglePlaying"></i>
  61. </p>
  62. <p class="control">
  63. <i class="icon-playlist"></i>
  64. </p>
  65. </p>
  66. </transition>
  67. <audio :src="currentSong.url" ref="audio" @canplay="ready" @error="error" @timeupdate="updateTime" @ended="end"></audio>
  68. </p>

打开播放器的状态

  1. import {mapGetters,mapMutations} from 'vuex';
  2. ...mapGetters([
  3. 'fullScreen',
  4. 'playList',
  5. 'currentSong',
  6. 'playing',
  7. 'currentIndex',
  8. ])

注意:不可在组件中直接赋值改版vuex 中的状态 this.fullScreen = false 需要通过mutations 改变,定义mutation-types 和mutations 然后 用vuex的 mapMutations 代理方法调用

  1. [types.SET_FULL_SCREEN](state, flag) {
  2. state.fullScreen = flag
  3. },
  4. import {mapGetters,mapMutations} from 'vuex';
  5. methods:{
  6. ...mapMutations({
  7. setFullScreen:"SET_FULL_SCREEN",
  8. }),
  9. back(){
  10. this.setFullScreen(false)
  11. },
  12. }

设置点击播放按钮方法

  1. <i :class="playIcon" @click="togglePlaying"></i>
  1. togglePlaying(){
  2. this.setPlayingState(!this.playing); //改变全局变量playing 的属性
  3. },
  4. // 然后watch 监听playing 操作实际的audio 标签的播放暂停
  5. watch:{
  6. playing(newPlaying){
  7. let audio = this.$refs.audio;
  8. this.$nextTick(() => {
  9. newPlaying ? audio.play():audio.pause();
  10. })
  11. }
  12. },
  13. // 用计算属性改变相应的播放暂停图标
  14. playIcon(){
  15. return this.playing? 'icon-pause':'icon-play'
  16. },

设置点击播放上一首和下一首按钮方法。用mapGetters 获取currentIndex 的值(加一或减一) 并改变,从而改变 currentSong 的状态,监听切换播放。判断播放列表界限重置。

  1. prev(){
  2.     if(!this.songReady){
  3.       return;
  4.     }
  5. let index = this.currentIndex - 1;
  6. if(index === -1){    //判断播放列表界限重置
  7. index = this.playList.length-1;
  8. }
  9. this.setCurrentIndex(index);
  10. if(!this.playing){  //判断是否播放改变播放暂停的icon
  11. this.togglePlaying();
  12. }
  13. this.songReady = false;
  14. },
  15. next(){
  16. if(!this.songReady){
  17.     return;
  18.    }
  19. let index = this.currentIndex + 1;
  20. if(index === this.playList.length){    //判断播放列表界限重置
  21. index = 0;
  22. }
  23. this.setCurrentIndex(index);
  24. if(!this.playing){
  25. this.togglePlaying();
  26. }
  27. this.songReady = false;
  28. },

监听audio 元素标签的canpaly 事件,当歌曲加载就绪 和 error 事件,当歌曲发生错误的时候,做用户体验,防止用户快速切换导致报错。

设置songReady 标志位 如果歌曲没有准备就绪,点击下一首的时候直接return false

  1. data(){
  2. return {
  3. songReady:false,
  4. }
  5. },
  6. ready(){
  7. this.songReady = true;
  8. },
  9. error(){
  10. this.songReady = true;
  11. },

进度条

audio元素监听 timeupdate 事件获取当前播放时间的 可读写属性 时间戳。用formt做格式化时间处理,(_pad 为补零函数 )

获取音频总时长 currentSong.duration

  1. <p class="progress-wrapper">
  2. <span class="time time-l">{{ format(currentTime) }}</span>
  3. <p class="progress-bar-wrapper">
  4. <progress-bar :percent="percent" @percentChange="onProgressBarChange"></progress-bar>
  5. </p>
  6. <span class="time time-r">{{ format(currentSong.duration) }}</span>
  7. </p>
  8. <audio :src="currentSong.url" ref="audio" @canplay="ready" @error="error" @timeupdate="updateTime" @ended="end"></audio>
  1. updateTime(e){
  2. this.currentTime = e.target.currentTime; // 获取当前播放时间段
  3. },
  4. format(interval){
  5. interval = interval | 0;
  6. const minute = interval/60 | 0;
  7. const second = this._pad(interval % 60);
  8. return `${minute}:${second}`;
  9. },
  10. _pad(num,n=2){
  11. let len = num.toString().length;
  12. while(len<n){
  13. num = '0' + num;
  14. len ++;
  15. }
  16. return num;
  17. },

建立progress-bar 组件 接收pencent 进度参数,设置进度条宽度和小球的位置。player组件 设置计算属性percent

  1. percent(){
  2. return this.currentTime / this.currentSong.duration  // 当前时长除以总时长
  3. },

progress-bar 组件

  1. <p class="progress-bar" ref="progressBar" @click="progressClick">
  2. <p class="bar-inner">
  3. <p class="progress" ref="progress"></p>
  4. <p class="progress-btn-wrapper" ref="progressBtn"
  5. @touchstart.prevent="progressTouchStart"
  6. @touchmove.prevent="progressTouchMove"
  7. @touchend="progressTouchEnd"
  8. >
  9. <p class="progress-btn"></p>
  10. </p>
  11. </p>
  12. </p>
  1. const progressBtnWidth = 16 //小球宽度
  2. props:{
  3. percent:{
  4. type:Number,
  5. default:0
  6. }
  7. },
  8. watch:{
  9. percent(newPercent){
  10. if(newPercent>=0 && !this.touch.initated){    
  11. const barWidth = this.$refs.progressBar.clientWidth - progressBtnWidth;
  12. const offsetWidth = newPercent * barWidth;
  13. this.$refs.progress.style.width = `${offsetWidth}px`;
  14. this.$refs.progressBtn.style.transform=`translate3d(${offsetWidth}px,0,0)`
  15. }
  16. }
  17. }

设置拖动

在进度条小按钮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),并且派发事件

  1. created(){
  2. this.touch = {};
  3. },
  4. methods:{
  5. progressTouchStart(e){
  6. this.touch.initiated = true;
  7. this.touch.startX = e.touches[0].pageX;
  8. this.touch.left = this.$refs.progress.clientWidth;
  9. },
  10. progressTouchMove(e){
  11. if(!this.touch.initiated){
  12. return;
  13. }
  14. let deltaX = e.touches[0].pageX - this.touch.startX;
  15. let offsetWidth = Math.min(this.$refs.progressBar.clientWidth - progressBtnWidth,Math.max(0,this.touch.left + deltaX));
  16. this._offset(offsetWidth);
  17. },
  18. progressTouchEnd(e){
  19. this.touch.initiated = false;
  20. this._triggerPercent();
  21. },
  22. progressClick(e){
  23. const rect = this.$refs.progressBar.getBoundingClientRect();
  24. const offsetWidth = e.pageX - rect.left;
  25. this._offset(offsetWidth);
  26. // this._offset(e.offsetX);
  27. this._triggerPercent();
  28. },
  29. _offset(offsetWidth){
  30. this.$refs.progress.style.width = `${offsetWidth}px`;
  31. this.$refs.progressBtn.style[transform] = `translate3d(${offsetWidth}px,0,0)`;
  32. },
  33. _triggerPercent(){
  34. const barWidth = this.$refs.progressBar.clientWidth - progressBtnWidth;
  35. const percent = this.$refs.progress.clientWidth / barWidth;
  36. this.$emit("percentChange",percent)
  37. }
  38. },

本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

更多vue学习教程请阅读专题《vue实战教程》

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在vue.js中如何整合mint-ui里的轮播图

在Jstree中如何实现选中父节点时被禁用的子节点也会选中

在Vue中关于过滤器filters的用法

在Javascript中自适应处理方法

以上就是在vue-music中关于Player播放器组件的使用说明的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行