vue音乐播放条

先看效果

再看代码

cpp 复制代码
<template>
  <div class="footer-player z-30 flex items-center p-2">
    <div v-if="isShow" class="h-12 w-60 overflow-hidden">
      <div :style="activeStyle" class="open-detail-control-wrap">
        <div class="flex h-full w-40 items-center">
          <div ref="triggerRef" class="relative" @click="handleArrowClick">
            <n-image
              class="size-12"
              :src="currentSong?.al?.picUrl"
              :preview-disabled="true"
              :style="{filter:isHover ? 'blur(1px)' : 'none'}"
            />
            <transition v-show="isHover" name="fade">
              <div class="flex-items-justify-center absolute left-0 top-0 z-10  size-12 bg-black/60">
                <n-icon :component="KeyboardArrowUpOutlined" size="35" color="white" />
              </div>
            </transition>
          </div>
          <div class="ml-4">
            <p class="flex items-center text-base">
              <n-ellipsis style="max-width: 150px">
                {{ currentSong?.name }}
              </n-ellipsis>
              <heart-icon
                :id="mainStore.currentPlaySong.id" class="ml-2" :like="mainStore.currentPlaySong.like"
                @like-success="likeSuccess"
              /> 
            </p>
            <n-ellipsis>
              <p>{{ formateSongsAuthor(currentSong?.ar || []) }}</p>
            </n-ellipsis>
          </div>
        </div>

        <div class="flex h-12 items-center">
          <n-icon
            size="35" :component="KeyboardArrowDownOutlined" class="ml-4"
            @click="mainStore.setShowMusicDetail(false)"
          />
          <div class="ml-4">
            <div class="circleContainer" @click="handleLikeHeartClick">
              <heart-icon
                :id="mainStore.currentPlaySong.id"
                ref="heardLikeRef" :like="mainStore.currentPlaySong.like"
                :size="25" :trigger-click="true" @like-success="likeSuccess"
              /> 
            </div>
          </div>
          <div class="circleContainer ml-4" @click="subscribeModalRef?.show()">
            <n-icon :component="AddBoxOutlined" :size="20" />
          </div>
        </div>
      </div>
    </div>

    <div :style="{opacity:isShow ? '1' : '0.6'}" class="control flex flex-1 flex-col items-center">
      <div v-if="!isShow" class="footer-player absolute z-50 w-full" />
      <div style="width:300px" class="flex items-center justify-between">
        <n-icon
          class="custom-icon" :size="22" :component="currentPlayModeIcon"
          @click="handlePlayModeClick"
        />
        <n-icon
          class="prev custom-icon" :size="22" :component="SkipPreviousSharp"
          @click="handlePrevClick"
        />
        <div
          class="flex size-8 items-center justify-center rounded-full  bg-neutral-200/60 
        hover:bg-neutral-200 dark:bg-slate-100/20 
        dark:hover:bg-slate-100/40" @click="togglePlayStatus"
        >
          <n-icon :size="mainStore.playing ? 14 : 20" :component="mainStore.playing ? StopIcon :PlayArrowSharp" 
        </div>
        <n-icon
          class="next custom-icon" :size="22" :component="SkipNextSharp"
          @click="handleNextClick"
        />
      </div>
      <div class="mt-1 flex items-center">
        <span v-if="isShow" class="mr-2 text-xs opacity-50">{{ currentPlayTime }}</span>
        <div class="flex flex-1 items-center" :style="{width:progressWidth+'px'}">
          <slider-bar
            v-model="percentage"
            :load-value="progressValue"
            @on-done="handleSliderDone"
            @change="handleSliderChange"
          />
        </div>
        <span v-if="isShow" class="ml-2 text-xs opacity-50">
          <n-time format="mm:ss" :time="currentSong?.dt" />
        </span>
      </div>
    </div>

    <div v-if="isShow" class="flex w-60 items-center justify-end">
      <n-popover
        placement="bottom"
        trigger="hover"
      >
        <template #trigger>
          <n-icon
            :component="volume === 0 ? VolumeOffRound : VolumeUpRound" :size="25" class="custom-icon mr-2"
            @click="handleVolumeClick"
          />
        </template>
        <n-slider
          :value="volume" vertical style="height:100px"
          @update-value="handleVolumeChange"
        />
      </n-popover>
      <n-icon
        :component="List" :size="25" class="custom-icon mr-2"
        @click="playListRef?.show()"
      />
    </div>

    <audio
      ref="audioRef"
      :src="currentSong?.url"
      preload="auto" @timeupdate="handleTimeupdate" @ended="handleEnded"
      @playing="handlePlaying" @progress="updateBuffer" @loadeddata="handleLoadeddata"
      @error="handleError" @waiting="handleWaiting" 
    />

    <play-list ref="playListRef" />
    <music-detail v-if="mainStore.currentPlaySong?.id" ref="musicDetailRef" />
    <subscribe-play-list-modal
      v-if="mainStore.currentPlaySong?.id" ref="subscribeModalRef" 
      :tracks="mainStore.currentPlaySong?.id"
    />
  </div>
</template>
相关推荐
蜚鸣1 天前
Vue的快速入门
vue
吃饭最爱2 天前
⽹络请求Axios的概念和作用
vue
魂尾ac2 天前
Django + Vue3 前后端分离技术实现自动化测试平台从零到有系列 <第一章> 之 注册登录实现
后端·python·django·vue
是罐装可乐3 天前
深入理解 Vue3 Router:三种路由模式的工作原理与实战应用
架构·vue·路由·history·hash·ssr·router
老华带你飞3 天前
租房平台|租房管理平台小程序系统|基于java的租房系统 设计与实现(源码+数据库+文档)
java·数据库·小程序·vue·论文·毕设·租房系统管理平台
zhz52143 天前
Spring Boot + Redis 缓存性能优化实战:从5秒到毫秒级的性能提升
java·spring boot·redis·缓存·vue
小胖墩有点瘦4 天前
【基于协同过滤的校园二手交易平台】
java·vue·毕业设计·springboot·计算机毕业设计·协同过滤·校园二手交易平台
小圣贤君4 天前
小说创作中的时间轴体验设计:事序图交互与用户体验优化
electron·vue·甘特图·时序图·写作软件
知识分享小能手5 天前
React学习教程,从入门到精通,React 构造函数(Constructor)完整语法知识点与案例详解(16)
前端·javascript·学习·react.js·架构·前端框架·vue
@AfeiyuO5 天前
分类别柱状图(Vue3)
typescript·vue·echarts