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

如何基于Vue3与Vuex Store实现歌曲结束自动播放下一曲

解决方案

一、解决歌曲结束自动播放下一曲的问题

你在loadTrack mutation中绑定ended事件时,主要遇到了函数上下文丢失和事件重复绑定的问题,以下是修复方案:

  1. 用箭头函数绑定事件,确保this指向Vuex Store实例,同时移除旧音频的事件监听避免重复触发:
loadTrack(state, track) {
    // 先处理旧音频:暂停并移除事件监听
    if (state.curr_track) {
        state.curr_track.pause();
        state.curr_track.removeEventListener("ended", onTrackEnded);
    }

    // 初始化新音频
    state.curr_track = new Audio();
    state.curr_track.id = track.id;
    state.curr_track.src = track.file;
    state.curr_track.name = track.name;
    state.curr_track.artists = track.artists;
    state.curr_track.album_name = track.album.name;
    state.curr_track.album_cover = track.album.img_cover;

    // 定义结束事件回调,用箭头函数保留Store上下文
    const onTrackEnded = () => {
        this.commit('playNext');
    };
    // 绑定结束事件
    state.curr_track.addEventListener("ended", onTrackEnded);

    state.curr_track.load();
    this.commit('playTrack');
}

这样歌曲播放结束时,会自动触发playNext mutation完成切歌逻辑。

二、解决duration赋值报错的问题

HTMLMediaElement的duration是只读属性,无法直接赋值,你可以通过两种方式处理:

方式1:利用音频自身事件获取真实时长

Audio元素会在加载元数据后自动填充duration,监听loadedmetadata事件即可获取:

state.curr_track.addEventListener('loadedmetadata', () => {
    console.log('音频实际时长:', state.curr_track.duration);
});

方式2:用自定义字段存储后端返回的时长

如果后端已经返回了时长数据,给Audio元素添加自定义属性(避免覆盖原生属性),或者在State中单独存储歌曲元数据:

// 方式1:给Audio添加自定义属性
state.curr_track._duration = track.duration;

// 方式2:在State中新增字段存储元数据
// 先修改State初始值:
state() {
    return {
        curr_track: null,
        curr_track_meta: null, // 新增字段存元数据
        track_list: null,
        isPlaying: false,
    };
}
// 然后在loadTrack中赋值:
state.curr_track_meta = {
    duration: track.duration,
    name: track.name,
    artists: track.artists
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:10:28