目前只封装了图片与视频,后续会加入excel的导入导出
<template>
<div class="img-upload">
<div class="img-upload-box">
<div v-for="file in value" :key="file.fileId" class="img-upload-item el-upload-list--picture-card">
<!-- 1图片 2视频 -->
<template>
<video v-if="file.type === 2" :src="file.url" :controls="false" controlslist="nodownload" style="width: 100%">
您的浏览器不支持 video 标签
</video>
<el-image
v-else
class="el-upload-list__item-thumbnail"
:src="file.url"
:alt="file.fileName"
/>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePreview(file)"
>
<i class="el-icon-circle-plus-outline"></i>
</span>
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</span>
</template>
</div>
</div>
<el-upload
v-if="value.length < maxCount && !disabled"
v-loading="uploadLoading"
element-loading-text="上传速度跟附件大小有关,一般在1分钟之内"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
class="upload-wrapper"
ref="upload"
action="/vue_admin/omp/exceptioncodeFlow/business/upload"
:show-file-list="false"
:before-upload="beforeUpload"
:on-success="uploadSuccess"
:on-error="uploadFail"
:multiple="true"
>
<div class="plus-btn">
<i class="el-icon-plus"></i>
</div>
</el-upload>
<div v-if="!disabled" class="el-upload__tip">
<div class="text" v-for="t in tips" :key="t">· {{ t }}</div>
</div>
<el-dialog custom-class="img-preview-dialog" :append-to-body="true" :visible.sync="dialogVisible" title="预览">
<el-image v-if="dialogType === 1" :src="dialogImageUrl" alt="" />
<video v-else :src="dialogImageUrl" controls="controls" controlslist="nodownload" style="width: 100%"></video>
<template #footer>
<el-button @click="dialogVisible = false;">取消</el-button>
</template>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'FileUpload',
props: {
disabled: Boolean,
// 图片属性数组
value: Array,
// 最大上传图片数量
maxCount: {
type: Number,
default: 1,
},
tips: {
type: Array,
default() {
return ['图片大小: 不超过5M; 支持图片格式:jpg/jpeg/png', '视频大小: 不超过100M; 支持视频格式: mp4/mov/rmvb'];
},
},
},
data() {
return {
uploadLoading: false,
dialogImageUrl: '',
dialogType: '',
dialogVisible: false,
};
},
methods: {
// 文件上传
beforeUpload(file) {
let fileName = file.name
let fileend = fileName.substring(fileName.lastIndexOf("."))
// 视频
const isVideo = ['.mp4', '.mov', '.rmvb'].includes(fileend);
// 图片
const isJPG = ['.jpg', '.jpeg', '.png'].includes(fileend);
if (!isVideo && !isJPG) {
this.$notify({
title: '提示',
message: '只能上传图片和视频,图片支持jpg/jpeg/png格式,视频支持mp4/mov/rmvb格式',
type: 'warning'
});
return false;
}
if (isVideo) {
const isLt100M = file.size / 1024 / 1024 < 100;
if (!isLt100M) {
this.$message.error('上传视频大小不能超过 100MB!');
return false;
}
}
if (isJPG) {
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isLt5M) {
this.$message.error('上传图片大小不能超过 5MB!');
return false;
}
}
this.uploadLoading = true;
return true;
},
// 文件上传成功
uploadSuccess(res) {
this.uploadLoading = false;
if (res.code == 0) {
if (res.data) {
const file = {
...res.data,
url: res.data.url.replace('home/file', process.env.NODE_ENV === 'development' ? 'http://172.31.47.193:9070/image/' : '/image'),
}
const files = file ? this.value.concat([file]) : this.value;
this.emitInput(files);
}
} else {
this.$message.error(res.message);
}
},
handleRemove(file) {
this.$confirm('确认删除?', '提示', {
type: 'warning',
}).then(() => {
const index = this.value.findIndex(ff => ff.fileId === file.fileId);
const list = [...this.value];
list.splice(index, 1);
this.emitInput(list);
})
},
handlePreview(file) {
this.dialogVisible = true;
this.dialogType = file.type;
this.dialogImageUrl = file.url;
},
emitInput(files) {
this.$emit('input', files);
},
uploadFail(err) {
this.uploadLoading = false;
this.$message.error(err.message || '上传失败');
},
},
};
</script>
<style lang="scss" scoped>
.img-upload {
.img-upload-box {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.img-upload-item {
width: 80px;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
border-radius: 8px;
border: 1px dashed #c0ccda;
margin: 10px 10px 10px 0;
padding: 10px;
}
}
}
.upload-wrapper {
width: 300px;
}
.plus-btn {
height: 80px;
width: 80px;
line-height: 80px;
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed #c0ccda;
border-radius: 8px;
i {
margin-top: inherit;
font-size: 24px;
}
}
.img-preview-dialog {
/deep/ .el-dialog__body {
text-align: center;
img {
max-width: 100%;
}
}
}
</style>
使用示例
图片回显示例
最新回复