Plyr与Vue.js:通过计算属性获取视频时长遇问题
解决Vue中Plyr视频时长获取的问题
看起来你在尝试动态获取Plyr视频时长时踩了几个典型的坑,我来帮你一步步梳理问题并给出解决方案:
核心问题分析
- 计算属性的用法错误:你直接把
setInterval的返回值赋值给了计算属性functionOfDuration,但Vue的计算属性要求必须是一个包含getter(可选setter)的对象,这就是你收到Getter is missing警告的原因。而且计算属性设计用来做纯同步的响应式推导,不适合用来处理定时轮询这种异步操作。 - 重复创建Plyr实例:不管是在计算属性还是
updatePosition方法里,你每次都new Plyr('#vidplayer'),这会导致多个Plyr实例绑定到同一个video元素,不仅浪费资源,还可能引发各种奇怪的行为。 - 低效的轮询方式:用
setInterval轮询readyState并不是最优解,Plyr本身提供了事件可以直接监听视频加载状态。
修正后的代码实现
模板部分
<div> duration: {{ videoDuration }} </div> <plyr> <video id="vidplayer" @timeupdate="updatePosition"> <source src="videos.mp4" type="video/mp4"> </video> </plyr>
组件脚本部分
export default { data() { return { videoDuration: 0, player: null // 保存Plyr实例,避免重复创建 }; }, mounted() { // 确保DOM渲染完成后初始化Plyr,只执行一次 this.player = new Plyr('#vidplayer'); // 监听视频元数据加载完成事件,这是获取时长的最佳时机 this.player.on('loadedmetadata', () => { this.videoDuration = this.player.duration; }); // 额外监听ready事件,确保播放器完全就绪(可选) this.player.on('ready', () => { if (this.player.duration) { this.videoDuration = this.player.duration; } }); }, methods: { updatePosition() { // 直接使用已初始化的实例,无需重复创建 this.videoDuration = this.player.duration; } }, beforeUnmount() { // 组件销毁前销毁播放器实例,避免内存泄漏 if (this.player) { this.player.destroy(); } } };
关键改进点说明
- 单例播放器实例:在
mounted钩子中初始化一次Plyr并保存到data,后续所有操作都复用这个实例,避免重复绑定。 - 事件驱动而非轮询:利用Plyr的
loadedmetadata事件(视频元数据加载完成时触发)来获取时长,比轮询readyState更高效可靠。 - 正确使用响应式数据:把时长存储在data的
videoDuration中,而非错误地用计算属性处理异步状态。 - 内存泄漏防护:在组件销毁前调用
player.destroy()清理播放器资源。
内容的提问来源于stack exchange,提问作者krumpelstiltskin
相关产品推荐
相关产品推荐

