先看效果
再看代码
<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>