013_Vue音乐播放器(playlist.vue 播放列表组件)

点击播放列表,出来显示当前的播放列表,可以进行点击跳转播放歌曲,切换播放状态

在state状态库中使用isShowPlayList来控制playlist组件的显隐,在mutations和getters定义相关的操作

在playlist的一些操作,如切换播放状态,可以抛出给player.vue组件处理。

playlist.vue 组件

<template>
  <transition appear mode="out-in">
    <div class="playlist" v-show="isShowPlayList" @click.self="set_isShowPlayList(false);">
      <div class="list-wrapper">
        <div class="list-header">
          <h1 class="title">
            <i @click="modeChange" :class="iconMode"></i>
            <span class="text">{{modeType}}</span>
            <span class="clear">
              <i class="el-icon-delete"></i>
            </span>
          </h1>
        </div>

        <scroll :data="playList">
          <div class="list-content">
            <ul>
              <li class="item" v-for="(item,index) in playList" :key="index" :style="isRedStyle(item)" @click="selectItem(item,index)">
                <span class="play">
                  <i style="vertical-align:top;" :class="getCurrentIcon(item)"></i>
                </span>
                <span class="text">{{item.filename}}</span>
                <span class="like">
                  <i class="el-icon-star-off" style="color:red"></i>
                </span>
                <span class="delete">
                  <i class="el-icon-circle-close"></i>
                </span>
              </li>
            </ul>
          </div>
        </scroll>

        <div class="list-operate">
          <div class="add">
            <i class="icon-add"></i>
            <span class="text">添加歌曲队列</span>
          </div>
        </div>

        <div class="list-close" @click="set_isShowPlayList(false);">
          <span>关闭</span>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
import { mapMutations, mapGetters } from "vuex";
import scroll from "../base/scroll";

export default {
  props: [],
  data() {
    return {
      modeType: ""
    };
  },
  methods: {
    //切换播放模式
    modeChange() {
      this.$emit("modeChange");
    },

    //关闭
    ...mapMutations({
      set_isShowPlayList: "set_isShowPlayList",
      set_currentIndex:"set_currentIndex",
    }),

    //根据当前播放歌曲显示播放图标
    getCurrentIcon(item) {
      if (item.album_id == this.currentSong.album_id) {
        return "el-icon-video-pause";
      } else {
        return "el-icon-video-play";
      }
    },

    //根据当前播放歌曲 标红
    isRedStyle(item){
        if(item.album_id==this.currentSong.album_id){
            return "color:#DAA520;"
        }
    },

    //点击歌曲跳转播放
    selectItem(item,index){
        //随机播放
        if(this.mode==2){
            //找到当前歌曲在播放列表中的 索引
            index =this.playList.findIndex((song)=>{
                return song.album_id==item.album_id;
            })
        }
        this.set_currentIndex(index);//设置歌曲索引
        this.set_playing(true);//设置播放状态为true(暂停状态下切歌)
    }
  },

  computed: {
    ...mapGetters([
      "playing", //播放状态
      "fullScreen", //是否全屏
      "playList", //播放列表
      "currentSong", //当前歌曲
      "currentIndex", //当前索引
      "mode", //播放模式
      "sequenceList", //顺序列表
      "isShowPlayList" //playList的显隐
    ]),

    //播放状态样式
    iconMode() {
      //mode : 0 顺序播放  1 单曲循环  2 随机播放
      if (this.mode === 0) {
        this.modeType = "顺序播放";
        return "el-icon-refresh-left";
      } else if (this.mode === 1) {
        this.modeType = "单曲循环";
        return "el-icon-refresh";
      } else {
        this.modeType = "随机播放";
        return "el-icon-connection";
      }
    }
  },

  components: {
    scroll
  }
};
</script>

<style lang="less" scoped>
.playlist {
  position: absolute;
  top: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.6);
  color: #5f9ea0;
  z-index: 999;
  .list-wrapper {
    position: absolute;
    bottom: 0;
    height: 50vh;
    background: rgba(0, 0, 0, 0.7);
    width: 100%;
    .list-header {
      .title {
        font-size: 1.2rem;
        height: 2rem;
        line-height: 2rem;
        padding-left: 1rem;
        .text {
        }
        .clear {
          position: absolute;
          right: 1rem;
        }
      }
    }
    .wrapper {
      height: 30vh !important;
    }
    .list-content {
      position: relative;
      ul {
        overflow: hidden;
        li.item {
          height: 1.5rem;
          line-height: 1.5rem;
          padding-left: 0.2rem;
          .current {
          }
          .play {
            display: inline-block;
          }
          .text {
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            width: 75vw;
            display: inline-block;
          }
          .like {
            position: absolute;
            right: 1rem;
            margin-right: 2rem;
            color: white;
          }
          .delete {
            position: absolute;
            right: 1rem;
            color: white;
          }
        }
      }
    }

    .list-operate {
      position: absolute;
      bottom: 3.2rem;
      left: 50%;
      transform: translateX(-50%);
      width: 100%;
      text-align: center;
      .add {
        .text {
          height: 2rem;
          line-height: 2rem;
          padding: 0.3rem 0.5rem;
          border-radius: 20px;
          border: 1px solid gray;
        }
      }
    }

    .list-close {
      position: absolute;
      bottom: 0;
      width: 100%;
      height: 3rem;
      line-height: 3rem;
      text-align: center;
      font-size: 1.5rem;
      background-color: rgba(0, 0, 0, 0.8);
      span {
      }
    }
  }
}
</style>

将列表滚动到当前播放歌曲

传入当前播放的歌曲,根据歌曲的album_id来判断,如果已经是处于当前的位置,则return,否则,根据refs来操作dom标签,根据传入li的索引,将歌曲列表滚动到头部。

然后在切换歌曲的时候调用该函数来进行scroll的偏移,由于bette-scroll在元素隐藏时无法计算高度,所以还要监听显隐属性,然后再次调用refresh刷新scroll组件。

删除一首歌曲

在Action文件中定义删除歌曲的函数,与插入歌曲的逻辑类似。

清空歌曲

弹窗确定是否清空歌曲列表

效果图:

发布了142 篇原创文章 · 获赞 54 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/CWH0908/article/details/103278765