因为项目的需求,要在页面上加载动态的音乐播放器,所以需要封装audio组件进行引入。
- 隐藏原生的audio
- 通过自定义的dom实现自定义样式
- 控制dom操作audio 对象的属性和方法
组件:
<template> <div> <audio @timeupdate="updateProgress" controls ref="audioRef"> <source :src="fileurl" /> 您的浏览器不支持音频播放 </audio> <div class="audio-right"> <div class="play-stop-icon" @click="playAudio"> <CaretRightOutlined v-if="audioStatus !== 'pause'" class="dialogAudioPlay" ></CaretRightOutlined> <PauseOutlined v-else class="dialogAudioPlay"></PauseOutlined> </div> <div class="progress-bar-bg" id="progressBarBg"> <Slider :tip-formatter="formatter" v-model:value="playTime" @change="sliderChange" /> </div> <div class="audio-time" style="min-height: 10px"> <span class="audio-length-current" id="audioCurTime">{{ audioStart }}</span >/ <span class="audio-length-total">{{ duration }}</span> </div> </div> </div></template><script lang="ts"> import { defineComponent, ref, reactive, watchEffect, inject, onMounted, nextTick, watch, computed, toRef, toRefs, } from 'vue'; import { CaretRightOutlined, PauseOutlined } from '@ant-design/icons-vue'; import { Slider } from 'ant-design-vue'; export default defineComponent({ components: { CaretRightOutlined, PauseOutlined, Slider, }, props: { fileurl: "", duration: "",//音频时长 }, setup(props, context) { let audioStatus = ref('play'); let audioStart = ref<number | string>('0:00'); let audioVolume = ref(0.5); let audioHuds = ref(false); let audioRef = ref<HTMLAudioElement | null>(null); let durationSecond = ref<number>(); let playPercentage = ref<number>(); let playTime = ref<number | string>('0:00'); function fetch() { let myVid = audioRef.value; if (!myVid) return; myVid.loop = false; // 监听音频播放完毕 myVid.addEventListener( 'ended', function () { audioStatus.value = 'play'; // 显示播放icon }, false, ); if (myVid != null) { myVid.oncanplay = function () { durationSecond.value = myVid?.duration; }; myVid.volume = 0.5; // 设置音量50% } } // 播放暂停控制 function playAudio() { let recordAudio = audioRef.value; // 获取audio元素 if (recordAudio?.paused) { recordAudio?.play(); audioStatus.value = 'pause'; } else { recordAudio?.pause(); audioStatus.value = 'play'; } } const formatter = (value: number) => { playTime.value = value; return audioStart.value; }; // 更新进度条与当前播放时间 function updateProgress(e) { playPercentage.value = e.target.currentTime / e.target.duration; } function sliderChange() { audioRef.value.currentTime = (Number(playTime.value) * durationSecond.value) / 100; audioRef.value.play(); } onMounted(() => { fetch(); }); return { audioStatus, audioStart, audioVolume, audioHuds, audioRef, fetch, playAudio, updateProgress, playTime, formatter, playPercentage, durationSecond, sliderChange, }; }, });</script><style lang="scss" scoped> </style>
具体样式就根据各自需求进行处理,主要控制部分逻辑还是在拖拽快进上面