• vue中使用h5 video标签实现弹窗播放本地视频


    参考h5 < video >标签的用法

    在开发过程中主要涉及到以下几个需要关注的点

    1.弹窗的打开关闭

    父组件中使用.sync绑定visible属性,可直接在子组件中关闭弹窗更新父组件传入的visible值;

    // 父组件中引用子组件
    <video-modal :visible.sync="showVideoModal">
    
    // 子组件中
    <el-dialog :visible="visible" @close="closeModal"> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // 子组件中关闭弹窗方法
    closeModal() {
        this.$emit("updata:visible", false);
    } 
    
    • 1
    • 2
    • 3
    • 4

    不过这样使用会导致每次重新打开视频弹窗进度条都会留在上一次打开的位置,所以需要在引用子组件外再嵌套一个div,利用v-if使其每次打开都重新渲染,从而解决进度条缓存的问题;

    <div v-if="showVideoModal">
        <video-modal :visible.sync="showVideoModal">
    </div> 
    
    • 1
    • 2
    • 3

    2. 本地视频资源路径的引入

    需要播放的视频是项目中的静态资源,由于弹窗组件需要支持可复用,所以视频路径不可写死,下面示例为视频名称自定义;

    <video
        ref="video"
        class="play-video"
        controls="controls"
        autoplay="autoplay"
    >
        <source :src="require('@/assets/videos/' + videoName + '.mp4')" type="video/mp4" />
    </video> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如果视频不在src目录下,而是public目录下则写法略有不同;

    computed: {
        src() {
            // 需要在js部分用计算属性定义
            return process.env.BASE_URL + "videos/" + this.videoName + ".mp4";
        }
    }, 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. 视频播放完毕自动关闭弹窗

    监听video标签的ended事件并关闭弹窗即可,vue生命周期中定义需要增加this.$nextTick,否则无法获取对应的dom元素;

    mounted() {
        this.$nextTick(() => {
            // 播放完毕自动关闭弹窗
            const eleVideo = document.querySelector(".play-video");
            eleVideo.addEventListener("ended", () => {
                this.closeVideoModal();
            }, false);
        });
    }, 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4. 视频在弹窗中自适应大小

    给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> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    RocketMQ源码阅读(九)DefaultMQProducer消息发送
    基于 SaaS 搭建的党建小程序源码系统 带完整的搭建教程
    AutoX-1. 网页瀑布流 && AutoX-2. 蚂蚁王国的蜂蜜
    LCR 078. 合并 K 个升序链表
    【高等数学基础进阶】定积分与反常积分-反常积分
    C/C++基础讲解(一百三十二)之经典篇(贪食蛇)
    基于Fomantic UI Web构建 个人导航站点网站源码 网站技术导航源码
    【GIS】地理坐标系与投影坐标系的区别
    IOC课程整理-17 Spring事件
    设计模式:适配器模式(C++实现)
  • 原文地址:https://blog.csdn.net/web2022050901/article/details/125520714