You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js音频播放器开发:Quasar滑块同步与暂停异常问题

解决Vue+Quasar音频播放器滑块实时更新与暂停卡顿问题

问题根源

你当前代码的核心问题是playAudio函数里的同步while循环,它会持续占用浏览器主线程,导致UI完全卡顿,无法响应暂停点击;同时循环里的curremtTime是拼写错误(应为currentTime),这也会导致进度更新失效。

解决方案

改用异步定时器来更新滑块进度,同时维护定时器引用,在暂停/音频结束时清除定时器,避免无效循环。另外需要监听音频加载事件获取正确时长,修正播放/暂停的逻辑判断。

修改后的完整代码

<template>
  <div style="min-height: 667px; overflow-y: scroll">
    <div class="bg-white flex flex-center" style="min-height: 40vh">
      <div class="absolute" style="width: 100%; max-width: 500px">
        <h3 class="text-center text-h4 text-primary text-weight-bold">
          WITHOUT VOCALS
        </h3>
        <div class="full-width flex flex-center">
          <q-btn
            flat
            round
            color="secondary"
            text-color="primary"
            icon="fa-solid fa-backward"
            class="q-ma-md"
            size="20px"
          />
          <q-btn
            flat
            round
            color="secondary"
            text-color="primary"
            :icon="vocalPlayIcon"
            size="30px"
            class="bg-secondary q-ma-md"
            @click="toggleAudioWithoutVocals()"
          />
          <q-btn
            flat
            round
            color="secondary"
            text-color="primary"
            icon="fa-solid fa-forward"
            class="q-ma-md"
            size="20px"
          />
          <audio
            style="display: none"
            id="audio-player-without-vocals"
            controls
          >
            <source src="~assets/audio/shinedown.mp3" type="audio/mpeg" />
            Your browser does not support the audio tag.
          </audio>
        </div>
        <div class="full-width" style="max-width: 800px">
          <q-slider
            v-model="vocalPlayTime"
            :min="0"
            :max="vocalAudioDuration"
            @input="seekAudio"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from "vue";

const vocalPlayIcon = ref("fa-solid fa-play");
const vocalPlayTime = ref(0);
const vocalAudioDuration = ref(0);
const vocalAudioObj = ref(null);
const progressTimer = ref(null); // 保存定时器ID

onMounted(() => {
  vocalAudioObj.value = document.getElementById("audio-player-without-vocals");
  
  // 监听音频加载完成事件,获取准确时长
  vocalAudioObj.value.addEventListener("loadedmetadata", () => {
    vocalAudioDuration.value = vocalAudioObj.value.duration;
  });

  // 监听音频结束事件,自动重置播放状态
  vocalAudioObj.value.addEventListener("ended", () => {
    clearInterval(progressTimer.value);
    vocalPlayIcon.value = "fa-solid fa-play";
    vocalPlayTime.value = 0;
  });
});

onUnmounted(() => {
  // 组件销毁时清除定时器,避免内存泄漏
  if (progressTimer.value) {
    clearInterval(progressTimer.value);
  }
});

const toggleAudioWithoutVocals = () => {
  if (vocalAudioObj.value.paused) {
    startPlay();
  } else {
    pausePlay();
  }
};

// 开始播放逻辑
const startPlay = () => {
  vocalPlayIcon.value = "fa-solid fa-pause";
  vocalAudioObj.value.play();
  
  // 启动定时器,每隔100ms更新进度(可根据需求调整间隔)
  progressTimer.value = setInterval(() => {
    vocalPlayTime.value = vocalAudioObj.value.currentTime;
  }, 100);
};

// 暂停播放逻辑
const pausePlay = () => {
  vocalAudioObj.value.pause();
  vocalPlayIcon.value = "fa-solid fa-play";
  // 清除定时器,停止进度更新
  clearInterval(progressTimer.value);
};

// 滑块拖动跳转音频位置
const seekAudio = () => {
  vocalAudioObj.value.currentTime = vocalPlayTime.value;
};
</script>

关键改动说明

  • 移除阻塞主线程的while循环,改用setInterval异步更新滑块进度,彻底解决浏览器卡顿问题。
  • 添加progressTimer引用,用于在暂停/音频结束时清除定时器,精准停止进度更新。
  • 监听音频loadedmetadata事件获取正确时长,解决初始时长为NaN的问题。
  • 监听音频ended事件,自动重置播放状态和滑块位置,提升用户体验。
  • 新增滑块拖动跳转功能(seekAudio),支持手动调整播放位置。
  • 组件销毁时清除定时器,避免内存泄漏。
  • 修正原代码中curremtTime的拼写错误。

内容的提问来源于stack exchange,提问作者Qiuzman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:50:32