APlayer 中文文档 下载 App

APlayer 销毁与重建最佳实践

什么时候需要销毁

以下场景需要主动销毁 APlayer 实例:

  1. 单页应用(SPA)路由切换:组件卸载时必须销毁
  2. 列表动态增删:播放器容器从 DOM 中移除时
  3. 完整重新初始化:参数变化后想从零开始
  4. 页面彻底关闭:beforeunload 时(可选)

基本销毁

ap.destroy();
ap = null;  // 清空引用

销毁后:

Vue / React 组件中

Vue 3 Composition API

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import 'APlayer/dist/APlayer.min.css';
import APlayer from 'APlayer';

const playerRef = ref(null);
let ap = null;

onMounted(() => {
    ap = new APlayer({
        container: playerRef.value,
        audio: [...]
    });
});

onBeforeUnmount(() => {
    if (ap) {
        ap.destroy();
        ap = null;
    }
});
</script>

React useEffect

import { useEffect, useRef } from 'react';
import 'APlayer/dist/APlayer.min.css';
import APlayer from 'APlayer';

export function Player() {
    const playerRef = useRef(null);
    const apRef = useRef(null);

    useEffect(() => {
        apRef.current = new APlayer({
            container: playerRef.current,
            audio: [...]
        });

        // 清理函数 = 组件卸载时执行
        return () => {
            if (apRef.current) {
                apRef.current.destroy();
            }
        };
    }, []);

    return <div ref={playerRef} />;
}

销毁后重建

销毁后可以直接在同一个容器里重新实例化:

// 第一次
const ap1 = new APlayer({ container: el, audio: [...] });
ap1.destroy();

// 第二次(用新的参数)
const ap2 = new APlayer({
    container: el,  // 同一个 DOM 元素
    theme: '#333',  // 不同主题色
    audio: [...]    // 不同的歌曲列表
});

不需要手动清空容器内容——destroy() 已经做了。直接 new 就行。

为什么必须销毁

内存泄漏

如果你不销毁就直接把容器从 DOM 中移除:

这就是内存泄漏。

播放器状态不一致

销毁后不重建,而只是"修改一下参数":

const ap = new APlayer({ ... });
// 错误的尝试:直接修改属性
ap.options.theme = '#333';  // 改了不会自动生效
ap.options.audio = [...];   // 也不会重新渲染

APlayer 在初始化时就根据参数创建好了 DOM 和内部状态。修改 ap.options 不会触发重新渲染。正确做法是销毁后重新创建。

多次 create 不 destroy

// 错误:每次路由切换都创建新实例,但旧的没销毁
router.onChange(function() {
    const ap = new APlayer({ ... });  // 旧的 ap 被覆盖了,但没销毁!
});

每次 new APlayer() 都会:

旧的仍然在运行——尤其是 player.play() 不会因为变量被覆盖就停止。你会得到多个看不见的播放器同时播放。

销毁 vs 暂停

对比项pause()destroy()
停止播放✅✅
释放事件监听❌✅
释放 DOM❌✅
后续可恢复✅❌
内存占用释放

暂停是临时停止播放,播放器还在;销毁是彻底清理。

自定义资源清理

如果你用了 customAudioType 创建了额外资源(如 Hls 实例、Blob URL),需要在 destroy 事件里手动清理:

let hlsInstance = null;

const ap = new APlayer({
    audio: [{ type: 'customHls', ... }],
    customAudioType: {
        customHls: function(audioElement, audio, player) {
            hlsInstance = new Hls();
            hlsInstance.loadSource(audio.url);
            hlsInstance.attachMedia(audioElement);
        }
    }
});

// 监听销毁事件,清理自己创建的资源
ap.on('destroy', function() {
    if (hlsInstance) {
        hlsInstance.destroy();
        hlsInstance = null;
    }
});