图片视频组件封装
<template> <div> <el-upload ref="upload" :class="disabled ? 'disabled' : ''" list-type="picture-card" :action="action" :file-list="newFileList" :disabled="disabled" :on-remove="handleRemove" :on-success="handleSuccess" :before-upload="beforeUpload" > <i slot="default" class="el-icon-plus"></i> <div slot="file" slot-scope="{ file }"> <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /> <span class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)" > <i class="el-icon-zoom-in"></i> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)" > <i class="el-icon-delete"></i> </span> </span> </div> <div slot="tip" class="el-upload__tip" v-if="!disabled"> 可以上传jpg/png/Jpeg格式图片或正确格式视频文件,上传文件大小不能超过 60MB! </div> </el-upload> <el-dialog :visible.sync="dialogVisible" append-to-body width="80%"> <div style="width:100%;text-align:center"> <img v-if="isShowImg" ref="dialogImg" :style="{width:'100%', 'aspect-ratio':dialogRatio }" :src="dialogUrl" /> <video v-else width="100%" height="600px" :src="dialogUrl" controls="controls" autoplay></video> </div> </el-dialog> </div> </template> <script> import util from "@/libs/util"; export default { props: { fileList: { type: Array, default: () => { return []; }, }, disabled: { type: Boolean, default: () => { return false; }, }, }, data() { return { newFileList:[], action: util.baseUrl + "/sdfs/file/uploadImage", dialogVisible: false, isShowImg: false, dialogUrl: "", dialogRatio:1, }; }, watch: { fileList: { handler(newV) { let newFileList = []; const videoType = ["mp4", "ogg", "flv", "avi", "wmv", "3gp", "mov"]; newFileList = this.fileList.map(item => { let url = item.url ? item.url : item; const type = url.split(".")[url.split(".").length - 1]; let file = { url: url } if (videoType.includes(type)) { file.videoUrl = file.url; this.getVideoBase64(url).then(res => { file.url = res; }) } return file; }) this.newFileList = newFileList; }, immediate: true }, dialogVisible(newV) { if(!newV) { this.isShowImg = true; this.dialogUrl = ""; } } }, methods: { handleRemove(file, fileList) { console.log(file) for (let i in this.newFileList) { if (file.uid == this.newFileList[i].uid) { this.newFileList.splice(i, 1); } } this.$emit("setFileList", this.newFileList); }, handleSuccess(res, file) { let _self = this; if (res.code !== '00000') { _self.$message({ message: '附件上传失败', type: 'error' }) _self.fileList.splice(_self.fileList.indexOf(file, 1)) } else { let data = { name: file.name, url: file.response.data, } const type = data.url.split(".")[data.url.split(".").length - 1]; const videoType = ["mp4", "ogg", "flv", "avi", "wmv", "3gp", "mov"]; if (videoType.includes(type)) { //视频附件,获取第一帧画面作为 封面展示 data.videoUrl = file.response.data; this.getVideoBase64(data.url).then(res => { data.url = res; }) } this.fileList.push(data); this.$emit("setFileList", this.fileList); } }, beforeUpload(file) { const isJPG = file.type === "image/jpeg" || file.type === "image/jpg" || file.type === "image/png"; const isVideo = [ "video/mp4", "video/ogg", "video/flv", "video/avi", "video/wmv", "video/3gp", "video/mov", ].indexOf(file.type) !== -1; if (!isJPG && !isVideo) { this.$message.error( "请确认上传图片为jpg/png/jpeg/格式,视频为正确格式!" ); return false; } const isLt60M = file.size / 1024 / 1024 < 60; if (!isLt60M) { this.$message.error('上传文件大小不能超过 60MB!'); return false } return (isJPG || isVideo) && isLt60M; }, handlePictureCardPreview(file) { if (file.videoUrl) { this.dialogUrl = file.videoUrl; this.isShowImg = false; }else { this.dialogUrl = file.url; this.isShowImg = true; setTimeout(() => { this.getImageSize(this.$refs.dialogImg).then(res => { this.dialogRatio = res; }) }) } this.dialogVisible = true; }, //获取图片比例 getImageSizeByUrl(url) { return new Promise(function (resolve, reject) { let image = new Image(); image.onload = function () { resolve(image.width/image.height); }; image.onerror = function () { reject(new Error('error')); }; image.src = url; }); }, async getImageSize(img) { if (img.naturalWidth) { // 适用于Firefox/IE9/Safari/Chrome/Opera浏览器 return img.naturalWidth/img.naturalHeight } else { return await this.getImageSizeByUrl(img.src); } }, /** * @description 获取视频第一帧作为回显封面 * @param {*} url * @return {*} */ getVideoBase64(url) { return new Promise(function (resolve, reject) { let dataURL = ''; let video = document.createElement("video"); video.setAttribute('crossOrigin', 'anonymous');//处理跨域 video.setAttribute('src', url); video.setAttribute('width', 400); video.setAttribute('height', 240); video.setAttribute('preload', 'auto'); video.addEventListener('loadeddata', function () { let canvas = document.createElement("canvas"), width = video.width, //canvas的尺寸和图片一样 height = video.height; canvas.width = width; canvas.height = height; canvas.getContext("2d").drawImage(video, 0, 0, width, height); //绘制canvas dataURL = canvas.toDataURL('image/jpeg'); //转换为base64 resolve(dataURL); }); }) } }, }; </script> <style lang="less" scoped> .disabled .el-upload--picture-card { display: none; } .el-upload-list__item>div { width: 100%; height: 100%; } </style>
let exhibitShow = this.formValidate.exhibitShow.map(item => { return item.videoUrl || item.url || item; }).join(',');
exhibitShow: data.exhibitShow ? data.exhibitShow.split(',').filter(item => item) : [],
exhibitShow:"http://49.7.218.51:9999/sdfs/static/image/28d4f32b-3e59-4c2b-8bfc-d88dae85e66e.png,http://49.7.218.51:9999/sdfs/static/image/1926e3a2-f581-43c8-9053-e9d3f10f68d1.png,http://49.7.218.51:9999/sdfs/static/image/dcccc445-c72f-4b6a-8f38-0a63f9790216.png"