首页 > 其他分享 >vue 视频上传组件

vue 视频上传组件

时间:2023-11-03 13:57:12浏览次数:30  
标签:vue item data height width video 组件 上传

组件:

<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"
>
<span
element-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-errors
return reject('请上传正确的视频格式!')
}

if (file.size / 1024 / 1024 > this.sizeLimit) {
// eslint-disable-next-line prefer-promise-reject-errors
return reject(`视频大小不能超过${this.sizeLimit}M!`)
}

if (this.videoList.length === this.numLimit) {
// eslint-disable-next-line prefer-promise-reject-errors
return 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 = 0
video.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://blog.ncmem.com/wordpress/2023/11/03/vue-%e8%a7%86%e9%a2%91%e4%b8%8a%e4%bc%a0%e7%bb%84%e4%bb%b6/

欢迎入群一起讨论

 

 

标签:vue,item,data,height,width,video,组件,上传
From: https://www.cnblogs.com/songsu/p/17807435.html

相关文章

  • 宝塔 nginx 运行 vue项目
    宝塔安装nginxnginx根目录:/www/server/nginx/html修改nginx配置下滑到70多行,添加server对象内容,内容如下server{listen82;server_nametest2;location/{roothtml/test2;indexindex.htmlindex.htm;......
  • vue图片上传视频
    图片上传是现在Web开发中常见的需求之一。而使用Vue框架可以使得这一过程更加方便和有效。在Vue中使用预先开发好的组件,可以快速地实现图片上传功能。//在Vue组件中引用插件importVueUploadComponentfrom'vue-upload-component'//在模板中引用组件上面的代码使用VueUplo......
  • 甘特图组件DHTMLX Gantt用例 - 如何拆分任务和里程碑项目路线图
    创建一致且引人注意的视觉样式是任何项目管理应用程序的重要要求,这就是为什么我们会在这个系列中继续探索DHTMLXGantt图库的自定义。在本文中我们将考虑一个新的甘特图定制场景,DHTMLXGantt组件如何创建一个项目路线图。用例-带有自定义时间尺度、拆分任务和文本标签的项目路线......
  • vue3 -点击按钮进入新的页面
    一、调用页面//路由import{useRouter}from'vue-routerlet$router=useRouter()//车组调整页面consthandleCar=(row:any)=>{ $router.push({path:"/test/edit",query:{setCode:row.setCode,lineName:row.lineName}})}二、新打开的页面importuseTagsViewSt......
  • 界面组件DevExtreme v23.1 —— UI模板库更新新功能
    在DevExtreme在v22.2版本中附带了针对Angular、React和Vue的新UI模板库,这个新的UI模板库包含多个响应式UI模板,您可以将其用作业务应用程序的起点,模板包括类似CRM的布局、仪表盘、身份验证表单等。在这篇文章中,我们将看看在v23.1发布周期中引入的与UI模板库相关的更新。DevExtreme......
  • vue3 用法汇总(二)
    1、列表中鼠标放在不同单元格显示不同的背景颜色<el-tablev-resize:44:data="tableData"class="tablemarking-table"borderstyle='margin:10px0px'highlight-current-rowelement-loadi......
  • vue上传视频框架
    在Web应用程序中经常需要用户上传视频,以便内容分享,教程和其他目的。Vue.js是一种流行的JavaScript框架,它提供了一种方便的方式来设计交互式和动态的用户界面,因此Vue上传视频框架是一种非常受欢迎的技术。Vue.js框架提供了各种插件和工具,它们可以帮助开发人员轻松地实现视频上传功......
  • Vue树形单选选择器
    调用页面SuperviseTimerModal.vue代码如下:<template><div><j-modalcentered:title="title":width="width":visible="visible":destroyOnClose="true"switchFullscreen......
  • 创建一个vue项目---全局环境搭建
    全局环境搭建一、环境准备1、安装node.js下载地址:https://nodejs.org/en/2、检查是否安装成功:输出版本号说明安装成功3、安装淘宝镜像(淘宝镜像速度比较快)npminstall-gcnpm-registry=https://registry.npm.taobao.org4、检查cnpm是否安装成功cnpm-v二、搭......
  • springboot-vue 项目
    一、后端 @Controller一般 在controller中return返回的是一个地址@RestController返回的是一个数据(json),在前后端分离都是用@RestController @RequestParam   与浏览器上的值作为绑定(如果name写错,也能传递),不过写了之后一定要传 @RequestBody 传递json格式......