Vue.js中如何实现歌曲播放时seekbar进度条自动同步移动
Vue.js 音频播放器进度条自动更新修复方案
进度条无法自动跟随播放移动的核心原因是未监听音频实例的timeupdate事件,播放过程中当前播放时间变动时,没有同步更新Vue实例中绑定进度条宽度的progress响应式变量。同时原代码还存在API调用错误、事件重复绑定、时间显示未同步的问题,按以下步骤修改即可:
第一步:调整模板代码
给时间节点、进度条DOM增加ref引用,绑定进度条点击跳转事件,去掉不必要的jQuery依赖:
<div class="playbackBar"> <span ref="currentTime" class="progressTime current">0:00</span> <div ref="progressBar" class="progressBar" @click="handleSeek"> <div class="progressBarBg"> <div :style="'width:'+progress+'%'" class="progress"></div> </div> </div> <span ref="remainingTime" class="progressTime remaining">0:00</span> </div>
第二步:修复脚本逻辑
补全进度更新监听、修正错误API、优化事件绑定逻辑,修改后完整脚本如下:
<script> export default { data(){ return{ current: {}, index: 0, isPlaying: false, progress: 0, songs: [ { title: 'Sample', artist: 'Sample Artist', src: '/storage/audio/sample.mp3' } ], player: new Audio() } }, methods: { // 秒数转 分:秒 格式工具方法 formatTime(seconds) { if(isNaN(seconds)) return '0:00' const min = Math.floor(seconds / 60) const sec = Math.floor(seconds % 60).toString().padStart(2, '0') return `${min}:${sec}` }, // 修复进度条点击跳转逻辑 handleSeek(e) { const barWidth = this.$refs.progressBar.offsetWidth const percentage = e.offsetX / barWidth * 100 // 修正原生Audio API:直接赋值currentTime属性实现跳转,不存在setTime方法 this.player.currentTime = this.player.duration * (percentage / 100) this.progress = percentage }, play(song){ if(typeof song.src != "undefined"){ this.current = song this.player.src = this.current.src } this.player.play() this.isPlaying = true; }, pause(){ this.player.pause(); this.isPlaying = false; } }, mounted() { // 核心:监听音频播放时间更新事件,同步进度条和时间显示 this.player.addEventListener('timeupdate', () => { // 计算当前播放进度百分比 this.progress = (this.player.currentTime / this.player.duration) * 100 // 更新当前播放时间文本 this.$refs.currentTime.textContent = this.formatTime(this.player.currentTime) // 更新剩余时间文本 this.$refs.remainingTime.textContent = this.formatTime(this.player.duration - this.player.currentTime) }) // 播放结束切歌事件只绑定一次,不要放在play方法里重复绑定 this.player.addEventListener('ended', () => { this.index++; if (this.index > this.songs.length - 1) { this.index = 0; } this.current = this.songs[this.index]; this.play(this.current); }) }, beforeUnmount() { // 组件销毁时释放音频资源,避免内存泄漏 this.player.pause() this.player.src = '' }, created(){ this.current = this.songs[this.index]; this.player.src = this.current.src; } } </script>
关键修复点说明
- 核心进度更新:通过监听音频原生
timeupdate事件(播放时每秒触发4~66次),实时计算进度百分比更新progress变量,驱动视图层进度条宽度变化 - 修正API错误:原生Audio实例跳转播放位置直接修改
currentTime属性即可,不存在setTime方法;定义的player本身就是Audio实例,没有player.audio的嵌套属性 - 修复事件泄漏:将
ended切歌监听从play方法移到挂载生命周期,全局只绑定一次,避免每次播放新增重复监听 - 补全时间联动:进度更新时同步刷新两侧的播放时间、剩余时间文本
- 移除jQuery依赖:通过Vue原生ref获取DOM元素计算点击位置,更符合框架开发规范
- 增加资源清理:组件销毁时暂停播放、释放音频资源,避免内存泄漏
内容的提问来源于stack exchange,提问作者Henry Oladeji
相关产品推荐
相关产品推荐

