如何基于Vue3与Vuex Store实现歌曲结束自动播放下一曲
解决方案
一、解决歌曲结束自动播放下一曲的问题
你在loadTrack mutation中绑定ended事件时,主要遇到了函数上下文丢失和事件重复绑定的问题,以下是修复方案:
- 用箭头函数绑定事件,确保
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
相关产品推荐
相关产品推荐

