时间:2022-10-03 11:32:46 | 栏目:vue | 点击:次
参考h5 < video >标签的用法
在开发过程中主要涉及到以下几个需要关注的点
父组件中使用.sync绑定visible属性,可直接在子组件中关闭弹窗更新父组件传入的visible值;
// 父组件中引用子组件 <video-modal :visible.sync="showVideoModal"> // 子组件中 <el-dialog :visible="visible" @close="closeModal">
// 子组件中关闭弹窗方法 closeModal() { this.$emit("updata:visible", false); }
不过这样使用会导致每次重新打开视频弹窗进度条都会留在上一次打开的位置,所以需要在引用子组件外再嵌套一个div,利用v-if使其每次打开都重新渲染,从而解决进度条缓存的问题;
<div v-if="showVideoModal"> <video-modal :visible.sync="showVideoModal"> </div>
需要播放的视频是项目中的静态资源,由于弹窗组件需要支持可复用,所以视频路径不可写死,下面示例为视频名称自定义;
<video ref="video" class="play-video" controls="controls" autoplay="autoplay" > <source :src="require('@/assets/videos/' + videoName + '.mp4')" type="video/mp4" /> </video>
如果视频不在src目录下,而是public目录下则写法略有不同;
computed: { src() { // 需要在js部分用计算属性定义 return process.env.BASE_URL + "videos/" + this.videoName + ".mp4"; } },
监听video标签的ended事件并关闭弹窗即可,vue生命周期中定义需要增加this.$nextTick,否则无法获取对应的dom元素;
mounted() { this.$nextTick(() => { // 播放完毕自动关闭弹窗 const eleVideo = document.querySelector(".play-video"); eleVideo.addEventListener("ended", () => { this.closeVideoModal(); }, false); }); },
给video标签设置合适的宽高,在利用object-fit: contain;属性即可。
最后附上完整代码
<template> <el-dialog class="video-dialog" :visible="visible" :title="title" width="75%" append-to-body @close="closeVideoModal"> <video ref="video" class="play-video" controls="controls" autoplay="autoplay" > <source :src="src" type="video/mp4" /> </video> </el-dialog> </template> <script> export default { name: "VideoModal", props: { visible: { type: Boolean, default: false }, // 父组件传参弹窗标题 title: { type: String, default: "" }, // 父组件传参要播放的视频名称 videoName: { type: String, default: "" } }, computed: { src() { return process.env.BASE_URL + "videos/" + this.videoName + ".mp4"; } }, mounted() { this.$nextTick(() => { // 播放完毕自动关闭弹窗 const eleVideo = document.querySelector(".play-video"); eleVideo.addEventListener("ended", () => { this.closeVideoModal(); }, false); }); }, methods: { closeVideoModal() { this.$emit("update:visible", false); } } }; </script> <style lang="scss" scoped> .play-video { object-fit: contain; width: 100%; height: 99.5%; } </style>