vue 视频上传组件

article/2025/9/18 5:38:24

在这里插入图片描述

组件:

<template><div class="upload-box"><div class="avatar-uploader-box"><!-- 图片预览 --><div :key="index" class="video-preview" v-for="(item, index) in videoList"><video v-if="item.videoLink" :src="`${videoBaseUrl}${item.videoLink}`" @mouseover.stop="item.isShowPopup = true" class="avatar">您的浏览器不支持视频播放</video><video v-else :src="item.url" @mouseover.stop="item.isShowPopup = true" class="avatar">您的浏览器不支持视频播放</video><!-- 显示查看和删除的按钮弹窗 --><div@mouseleave="item.isShowPopup = false"class="avatar-uploader-popup"v-show="(item.videoLink || item.url) && item.isShowPopup"><i @click="previewVideo(item)" class="el-icon-zoom-in"></i><i @click="deleteVideo(index)" class="el-icon-delete"></i></div></div><!-- 方框样式 --><el-upload:action="actionUrl":auto-upload="false":on-change="handleAvatarChange":show-file-list="false"class="avatar-uploader"ref="avatarUploader"v-show="uploadShow"><spanelement-loading-background="rgba(0, 0, 0, 0.8)"element-loading-spinner="el-icon-loading"element-loading-text="上传中"style="display:block;"v-loading="loading"><i class="el-icon-plus avatar-uploader-icon"></i></span></el-upload><!-- 上传提示文字样式 --><div class="upload-tip"><slot></slot></div></div><!-- 查看大图 --><el-dialog :visible.sync="dialogVisible" append-to-body center title="视频查看" :before-close="handleClose"><video :src="videoSrc" ref="video" controls alt width="100%">您的浏览器不支持视频播放</video></el-dialog></div>
</template><script>
export default {name: 'UploadVideo',components: {},props: {videos: {type: Array,default: function() {return []}},numLimit: {// 最大允许上传个数type: Number,default: 1},sizeLimit: {// 最大单文件大小type: Number,default: 50},videoBaseUrl: {// 已上传图片服务器路径type: String,required: true}},data() {return {loading: false,dialogVisible: false,videoList: [],videoSrc: '',actionUrl: ''}},computed: {uploadShow() {return this.videos.length < this.numLimit}},watch: {videos: {handler() {const isArray = Array.isArray(this.videos)if (isArray && this.videos.length > 0) {this.videos.map(item => {item.isShowPopup = false})this.videoList = JSON.parse(JSON.stringify(this.videos))} else {this.videoList = []}},deep: true,immediate: true}},created() {},methods: {// 上传之前beforeAvatarUpload(file) {return new Promise((resolve, reject) => {if (['video/mp4', 'video/ogg', 'video/flv', 'video/avi', 'video/wmv', 'video/rmvb', 'video/mov'].indexOf(file.raw.type) == -1) {// eslint-disable-next-line prefer-promise-reject-errorsreturn reject('请上传正确的视频格式!')}if (file.size / 1024 / 1024 > this.sizeLimit) {// eslint-disable-next-line prefer-promise-reject-errorsreturn reject(`视频大小不能超过${this.sizeLimit}M!`)}if (this.videoList.length === this.numLimit) {// eslint-disable-next-line prefer-promise-reject-errorsreturn reject(`最多上传${this.numLimit}个视频`)}resolve('符合表單規則')})},// 上传改变async handleAvatarChange(file, fileList) {try {await this.beforeAvatarUpload(file)this.uploadImgApi(file)} catch (e) {this.$message.warning(JSON.stringify(e))}},// 上传视频准备uploadImgApi(data) {console.log(data, 'upload**')const videoSrc = URL.createObjectURL(data.raw)this.videoList.push({videoFile: data,url: videoSrc,isShowPopup: false})this.$emit('change', this.videoList)},// 预览视频previewVideo(data) {if (data.videoLink) {this.videoSrc = `${this.videoBaseUrl}${data.videoLink}`} else {this.videoSrc = data.url}this.dialogVisible = true},// 删除视频deleteVideo(index) {this.$emit('delete', index)},handleClose() {const video = document.getElementsByTagName('video')[1]if (!video.paused) {video.currentTime = 0video.pause()}this.dialogVisible = false}}
}
</script><style lang="scss">
$width: 90px;
$height: 90px;.upload-box {.avatar-uploader-box {position: relative;display: flex;flex-direction: row;flex-wrap: wrap;padding-bottom: 20px;min-width: 350px;.avatar-uploader {.el-upload {width: $width;height: $height;border: 1px dashed #d9d9d9;border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;&:hover {border-color: #409eff;}.el-loading-spinner {width: $width;height: $height;position: relative;display: flex;flex-direction: column;align-items: center;justify-content: center;margin-top: 0;top: 0;.el-loading-text {margin: 0;}}}.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: $width;height: $height;line-height: $height;text-align: center;}}.video-preview {position: relative;padding-right: 20px;.avatar {width: $width;height: $height;display: block;border-radius: 6px;}.avatar-uploader-popup {position: absolute;top: 0;left: 0;z-index: 2;width: $width;height: $height;background: rgba($color: #000000, $alpha: 0.5);display: flex;justify-content: center;align-items: center;color: #fff;font-size: 20px;border-radius: 6px;i {width: 30%;text-align: center;padding: 0 5%;font-size: 24px;}}}.upload-tip {position: absolute;bottom: 0;left: 0;font-size: 12px;color: #606266;max-width: 350px;line-height: 20px;}}
}
</style>

页面引入:

import UploadVideo from '@c/UploadVideo'
components: { UploadVideo }
<upload-video:videos="videoInfo.allVideo":videoBaseUrl="IMAGEURL"@delete="deleteVideo"@change="getVideo" >
</upload-video>

data数据:

videoInfo: {allVideo: [],deleteVideo: []
}

视频上传:(此处只是上传到暂存区,真正上传是在提交表单时)

getVideo(event) {this.videoInfo.allVideo = event
}

视频删除:

deleteVideo(index) {const video = this.videoInfo.allVideo[index]if (video.videoLink) {this.videoInfo.deleteVideo.push(video)}this.videoInfo.allVideo.splice(index, 1)
}

在提交表单时上传:

uploadFiles() {const uploadList = []this.videoInfo.allVideo.map(item => {console.log(item, 'video')const videoFile = new FormData()if (!item.videoLink) {videoFile.append('file', item.videoFile.raw)videoFile.append('fileTag', 'video')uploadList.push(new Promise((resolve, reject) => {return ImgServe.uploadSingleFile(videoFile).then(res => {if (res.data.code === 200) {resolve(res.data.data)} else {this.$message('上传视频失败!')}})}))}})return Promise.all(uploadList)
}

*:分开上传是为了杜绝服务器脏数据
ImgServe.uploadSingleFile(videoFile)这儿是上传到服务器的接口,替换为自己的写法即可


http://chatgpt.dhexx.cn/article/Rg8MJE1N.shtml

相关文章

Vue视频流播放器 Vue-Core-Video-Player

最近遇到点需求&#xff0c;领导要求能四宫格、九宫格的视频流播放器&#xff0c;还要能随意切换播放地址&#xff0c;一开始想用Vue-Video-Player解决问题的&#xff0c;但越用越不爽&#xff0c;试试别的~ Vue-Core-Video-Player 注&#xff1a;在多屏的时候会互相干扰&…

Vue实现视频播放

1.使用html的video标签(适合pc端&#xff0c;支持Ogg、MPEG4、WebM格式) &#xff08;1&#xff09;安装video.js插件 cnpm install --save video.js&#xff08;2&#xff09;在main.js中导入video.js import Video from video.js import video.js/dist/video-js.css(3)使用…

vue-mini-player vue视频播放组件

基于 Vue 的一个轻量级视频播放组件&#xff0c;适配 PC 和移动端 vue-mini-player使用方法&#xff1a; 安装 npm install vue-mini-player -S// main.js import vueMiniPlayer from vue-mini-player import vue-mini-player/lib/vue-mini-player.css Vue.use(vueMiniPlaye…

Vue视频播放进行+水印的截图

需求 视频相关项目&#xff0c;有时候需要对视频进行截图的&#xff0c;图片一般加上水印。 这里展示下普通视频播放和直播视频播放的加水印方式。 资源 测试需要的视频资源用的 阿里视频中心 video播放视频 一些非直播、不复杂的视频播放需求&#xff0c;直接用这个就好…

vue 视频 时间进度条组件

vue 视频 时间进度条组件 有些视频是以视频流的形式进行渲染的&#xff0c;没有视频滚动条&#xff0c;所以就写了24h的时间组件 实现思路&#xff1a; 1&#xff0c;24h的时间刻度线总宽度为12960px 2&#xff0c;点击24h线的某一点&#xff0c;获取这一点离左侧原点的距离&a…

vue视频通话(Agora声网)

文章目录 声网简介语音视频通话API互动直播API实时消息API实时录制API实时码流加速API水晶球Agora Analytics 质量监控平台 基于声网实现视频通话注册配置实现音视频通话基本逻辑创建对象加入频道创建轨道订阅轨道 基于以上步骤封装组件导入注册使用项目页面注意事项GitHub链接…

vue 视频播放插件VideoPlayer

vue 视频播放插件VideoPlayer 1.npm install vue-video-player --save 2.main.js引入 import VideoPlayer from vue-video-player import vue-video-player/src/custom-theme.css import video.js/dist/video-js.cssVue.use(VideoPlayer)

vue 视频播放

一、概述 基于 Vue 的一个轻量级视频播放组件&#xff0c;适配 PC 和移动端。 官方链接&#xff1a;https://webweifeng.github.io/vue-mini-player/ 特色 1.轻量级 HTML5 播放器&#xff0c;精美 UI 控件&#xff0c;简单易上手 2.提供以 npm 的形式安装提供全局组件 3.多格式…

VUE视频

1.Vue后台脚手架安装过程&#xff1a;node.js

vue 视频截屏

video播放视频&#xff0c;一键截屏功能实现&#xff08;2种方式&#xff09; 1.canvas <template><div class"hik-box"><canvas style"display:none;width:200px;height:200px" id"myCanvas"></canvas><video wid…

Vue视频学习

黑马程序员vue前端基础教程-4个小时带你快速入门vue_哔哩哔哩_bilibili vue的el挂载点 id选择器&#xff0c;class选择器&#xff0c;元素选择器&#xff0c;推荐使用id选择器&#xff0c;因为id选择器唯一 vue的数据对象 vue开发网页&#xff1a; v-text v-html:解析返回的…

Vue2视频播放(Video)

Vue3视频播放&#xff08;Video&#xff09; 可自定义设置以下属性&#xff1a; 视频文件url&#xff08;src&#xff09;&#xff0c;必传&#xff0c;默认 &#xff0c;支持网络地址https和相对地址require(...) 视频封面url&#xff08;poster&#xff09;&#xff0c;默…

vue实现视频播放器功能,你学会了吗

&#x1f48c; 作者简介 &#x1f4d6; 个人介绍&#xff1a;小伙伴们&#xff0c;大家好&#xff01;我是水香木鱼&#xff0c;【前端领域创作者】&#x1f61c;&#x1f4dc; CSDN主页&#xff1a;水香木鱼&#x1f4d1; 个人博客&#xff1a;陈春波&#x1f3a8; 系列专栏&…

测试开发工程师成长日记001 - 敏捷测试、CI/CD/CT、DecOps的一些介绍

始终都没有很坚定想去做一份职业&#xff0c;大概就是缺少对互联网的热爱与坚持&#xff0c;对于我个人而言&#xff0c;大概需要的是简单而明确的方向&#xff0c;比如考研&#xff1a;选中一个学校并开始各个科目的学习和延伸。但是&#xff0c;找工作完全不一样&#xff0c;…

浅谈弱网测试及QNET

最近工作中需要进行弱网测试&#xff0c;所以在此将自己遇到的一些问题记录一下。本文是基于QNET进行的弱网测试。**首先弱网测试是什么&#xff1f;**模拟各种弱网环境&#xff0c;借助丢包、延时等弱网场景测试对弱网的处理机制&#xff0c;以游戏为例&#xff0c;就是保证前…

shell脚本测试

目录 test命令进行测试 1.比较大小 2.关于文件的权限检测&#xff08;-x常用&#xff09; 3.1测试文件是否存在&#xff08;-f&#xff0c;-d&#xff09; 4.多种条件的判断&#xff08;-a -o常用&#xff09; 5.判断字符串是否相等 expr命令 数值比较符号 逻辑判断脚本…

【Cmake】Ctest测试工具

目录 前言 一、初识CTest 二、使用方法 三、完整的简单测试工程 附录 附录一 cmake命令 enable_testing add_test 前言 原文&#xff1a;CTest - https://www.cnblogs.com/457220157-FTD/p/4139149.html 一、初识CTest CTest是CMake集成的一个测试工具&#xff0c;在使…

软件测试常见面试题

1、软件的含义 程序、数据以及相关文档的集合。 2、测试与调试的区别是什么&#xff1f; 测试是测试人员进行&#xff0c;主要目标是发现、报告、跟踪缺陷&#xff1b; 调试是开发人员进行&#xff0c;主要目标是定位缺陷位置、分析缺陷原因、修复缺陷。 3、IEEE是什么意思…

Web服务稳定性测试 负载测试 可靠性测试 方案 测试报告

注&#xff1a; 1. 程序员做的测试 2. 测试报告文档原稿在上传审核中&#xff0c;请等待 审核好了&#xff1a;https://download.csdn.net/download/yiquan_yang/12694138 1 概述 1.1 背景 系统的稳定性是系统长期稳定运行能力&#xff0c;需要时间累积才能度量。平台的某些问…

NFC测试

NFC功能点介绍&#xff1a; NFC英文全称Near Field Communication&#xff0c;近距离无线通信。 NFC采用主动和被动两种读取模式&#xff0c;NFC应用模式分为三种&#xff1a; 1、NFC卡模式&#xff08;被读模式&#xff0c;手机终端可以模拟成为一张普通的非接触卡被pos机读取…