factory_web/src/components/scUpload/multiple.vue

204 lines
5.7 KiB
Vue

<template>
<div class="sc-upload-multiple">
<div class="sc-upload-list">
<ul>
<li v-for="(file, index) in fileList" :key="index">
<div v-if="file.status!='success'" class="sc-upload-item" v-loading="true" element-loading-background="rgba(0, 0, 0, 0.5)">
<el-image class="image" :src="file.tempImg" fit="cover" :z-index="9999"></el-image>
</div>
<div v-else class="sc-upload-item">
<div class="mask">
<span class="del" @click.stop="del(index)"><i class="el-icon-delete"></i></span>
</div>
<el-image class="image" :src="file.url" fit="cover" :preview-src-list="preview" hide-on-click-modal append-to-body>
<template #placeholder>
<div class="image-slot">
<i class="el-icon-more"></i>
</div>
</template>
</el-image>
</div>
</li>
</ul>
</div>
<div class="sc-upload-uploader">
<el-upload ref="upload" class="uploader" :action="action" :accept="accept" multiple :show-file-list="false" :file-list="defaultFileList" :before-upload="before" :on-progress="progress" :on-success="success" :on-change="change" :on-remove="remove" :on-error="error" :http-request="request">
<div class="file-empty">
<i :class="icon"></i>
<h4 v-if="title">{{title}}</h4>
</div>
</el-upload>
</div>
<el-input v-model="value" style="display:none"></el-input>
</div>
</template>
<script>
import API from "@/api";
export default {
props: {
modelValue: { type: String, default: "" },
action: { type: String, default: "" },
apiObj: { type: Object, default: () => {} },
accept: { type: String, default: ".jpg, .png, .jpeg, .gif" },
maxSize: { type: Number, default: 10 },
title: { type: String, default: "" },
icon: { type: String, default: "el-icon-plus" }
},
data(){
return {
value: "",
defaultFileList: [],
fileList: []
}
},
watch:{
modelValue(){
this.$refs.upload.uploadFiles=this.modelValuetoArr
this.fileList = this.modelValuetoArr
this.value = this.modelValue
},
fileList: {
handler(){
if(this.isAllSuccess){
this.$emit('update:modelValue', this.fileListtoStr);
}
},
deep: true
}
},
computed: {
modelValuetoArr(){
return this.toArr(this.modelValue)
},
fileListtoStr(){
return this.toStr(this.fileList)
},
preview(){
return this.fileList.map(v => v.url)
},
isAllSuccess(){
var all_length = this.fileList.length;
var success_length = 0
this.fileList.forEach(item => {
if(item.status == "success"){
success_length += 1
}
})
return success_length == all_length
}
},
mounted() {
this.defaultFileList = this.toArr(this.modelValue);
this.fileList = this.toArr(this.modelValue)
this.value = this.modelValue
},
methods: {
//默认值转换为数组
toArr(str){
var _arr = [];
var arr = str.split(",");
arr.forEach(item => {
if(item){
_arr.push({
name: "F",
status: "success",
url: item
})
}
})
return _arr;
},
//数组转换为原始值
toStr(arr){
var _arr = [];
arr.forEach(item => {
_arr.push(item.url)
})
var str = _arr.join(",")
return str;
},
before(file){
const maxSize = file.size / 1024 / 1024 < this.maxSize;
if (!maxSize) {
this.$message.warning('上传文件大小不能超过 10MB!');
return false;
}
},
change(file, fileList){
file.tempImg = URL.createObjectURL(file.raw);
this.fileList = fileList
},
success(res, file){
file.url = res.data.src
},
progress(){
},
remove(){
},
error(err){
this.$notify.error({
title: '上传文件错误',
message: err
})
},
del(index){
this.fileList.splice(index, 1);
},
request(param){
var apiObj = API.default.upload;
if(this.apiObj){
apiObj = this.apiObj;
}
const data = new FormData();
data.append("file", param.file);
apiObj.post(data).then(res => {
param.onSuccess(res)
}).catch(err => {
param.onError(err)
})
}
}
}
</script>
<style scoped>
.el-form-item.is-error .sc-upload-uploader {border: 1px dashed #F56C6C;}
.sc-upload-multiple {display: inline-block;}
.sc-upload-list {display: inline-block;}
.sc-upload-list li {list-style: none;display: inline-block;width: 120px;height: 120px;margin-right: 10px;vertical-align: top;box-sizing: border-box;}
.sc-upload-item {position: relative;width: 100%;height: 100%;}
.sc-upload-item .mask {display: none;position: absolute;top:0px;right:0px;line-height: 1;z-index: 1;}
.sc-upload-item .mask span {display: inline-block;width: 25px;height:25px;line-height: 23px;text-align: center;cursor: pointer;color: #fff;}
.sc-upload-item .mask span i {font-size: 12px;}
.sc-upload-item .mask .del {background: #F56C6C;}
.sc-upload-item:hover .mask {display: inline-block;}
.sc-upload-list .image {width: 100%;height: 100%;}
.sc-upload-list .image-slot {display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;background: #f5f7fa;color: #909399;}
.sc-upload-list .image-slot i {font-size: 20px;}
.sc-upload-uploader {border: 1px dashed #d9d9d9;width: 120px;height: 120px;display: inline-block;vertical-align: top;box-sizing: border-box;}
.sc-upload-uploader:hover {border: 1px dashed #409eff;}
.sc-upload-uploader .uploader {width: 100%;height: 100%;}
.sc-upload-uploader:deep(.el-upload) {width: 100%;height: 100%;}
.sc-upload-uploader .file-empty {width: 100%;height: 100%;line-height: 1;display: flex;flex-direction: column;align-items: center;justify-content: center;}
.sc-upload-uploader .file-empty i {font-size: 28px;color: #8c939d;}
.sc-upload-uploader .file-empty h4 {font-size: 12px;font-weight: normal;color: #8c939d;margin-top: 10px;}
</style>