<template>
<div class="file-box">
<div class="file-list">
<div class="item"
v-for="(item, index) in binaryFile"
:key="index"
:style="{ width: width, height: height }">
<img @click="showImg(item.url)"
v-if="type == 'image'"
:src="item.url" />
<video controls
v-else-if="type == 'video'"
:src="item.url" />
<i v-if="!disabled && limit != 0"
@click="handleRemove(item, index)"
class="close el-icon-close"></i>
<div v-if="item.loading"
class="loading"></div>
</div>
<div v-if="binaryFile.length < limit && !disabled"
class="file-btn"
@click="handleUpload"
:style="{ width: width, height: height }">
<i class="el-icon-plus"
:style="{ lineHeight: `calc(${height} - 8px)` }"><span>{{ title }}</span></i>
</div>
<input ref="upload"
@change="handleUploadChange"
multiple="multiple"
type="file" />
</div>
</div>
</template>
<script>
import { uploadFile } from '@/api/common';
import { Message } from 'element-ui';
export default
{
props:
{
title:
{
default: "",
type: String
},
width:
{
default: "70px",
type: String
},
height:
{
default: "70px",
type: String
},
limit:
{
default: 1,
type: Number
},
value:
{
default: "",
type: [Array, String]
},
type:
{
default: "image",
type: String
}
},
inject:
{
elForm:
{
default: ''
},
elFormItem:
{
default: ''
}
},
data()
{
return {
fileList: [],
disabled: false,
binaryFile: [],
is_one_loading: false
}
},
computed:
{
isLoading()
{
let loading = true;
for (let index = 0; index < this.binaryFile.length; index++)
{
const element = this.binaryFile[index];
if (element.loading)
{
loading = false;
}
}
return loading;
}
},
watch:
{
binaryFile:
{
handler()
{
if (this.binaryFile.length > 0)
{
if (this.limit == 1 && typeof this.value == 'string')
{
this.$emit("input", this.binaryFile[0].url);
}
else
{
this.$emit("input", this.binaryFile.map(item => item.url));
}
}
else
{
if (this.limit == 1 && typeof this.value == 'string' && this.value != '')
{
this.$emit("input", '');
}
else if (this.value.length > 0)
{
this.$emit("input", []);
}
}
},
deep: true
},
value:
{
immediate: true,
deep: true,
handler(v)
{
if (this.limit == 1 && this.value != '' && this.binaryFile.length == 0 && !Array.isArray(this.value))
{
this.binaryFile = [{ url: this.value, loading: false }]
}
else if (Array.isArray(this.value) && this.value.length > 0 && this.binaryFile.length == 0)
{
this.binaryFile = this.value.map(item =>
{
return { url: item, loading: false }
})
}
else if (this.value.length == 0 && this.binaryFile.length != 0)
{
this.binaryFile = [];
}
console.log( this.binaryFile)
}
}
},
methods:
{
showImg(link)
{
this.$ImagePreview([{ thumbUrl: link, url: link }], 0);
},
handleUpload()
{
this.$refs['upload'].click()
},
/**
* @param {Event} event
*/
async handleUploadChange(event)
{
let fileList = event.target.files;
let maxLength = this.limit - this.binaryFile.length;
fileList.forEach((item, index) =>
{
if (index >= maxLength) return;
this.$store.dispatch("updateUploadLimit", 1);
let url = window.URL.createObjectURL(item);
let fileIndex = this.binaryFile.length + index;
this.binaryFile.push({ loading: true, url, index: fileIndex });
this.uploadImage(item, fileIndex).then(({ index, url }) =>
{
this.binaryFile.forEach((item) =>
{
if (item.index == index)
{
item.loading = false;
item.url = url;
}
});
});
});
this.$refs["upload"].value = "";
},
/**
* @param {File} file
*/
async uploadImage(file, s)
{
let formData = new FormData();
formData.append("file", file);
var appId = sessionStorage.getItem("appCode") || "1";
var appkey = appId == "2" ? "czzg" : appId == "3" ? "jlm" : "jdzg";
formData.append("appKey", appkey);
let { data } = await uploadFile(formData)
.then((r) => r)
.catch((e) => e);
await this.$store.dispatch("updateUploadLimit", -1);
if (data && data.code == 0)
{
return { index: s, url: data.data.fileUrl };
}
else
{
this.binaryFile.splice(s, 1);
}
},
handleRemove(item, index)
{
if (this.binaryFile[index].loading)
{
return Message.error("正在上传中, 请勿删除!");
}
this.binaryFile.splice(index, 1);
},
},
mounted()
{
this.$nextTick(() =>
{
if (this.type == "image")
{
this.$refs["upload"].setAttribute("accept", "image/*");
}
else if (this.type == "video")
{
this.$refs["upload"].setAttribute("accept", "video/*");
}
this.disabled = (this.elForm || {}).disabled;
});
},
};
</script>
<style lang="less"
scoped>
.file-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.item,
.file-btn {
border: 1px solid #ccc;
margin-right: 10px;
margin-bottom: 10px;
video,
img {
width: 100%;
height: 100%;
}
i.el-icon-plus {
display: block;
font-size: 28px;
color: #8c939d;
text-align: center;
}
}
.item {
position: relative;
i.close {
position: absolute;
top: -5px;
right: -5px;
background-color: red;
width: 15px;
height: 15px;
border-radius: 50%;
text-align: center;
line-height: 15px;
font-size: 12px;
cursor: pointer;
color: #fff;
z-index: 10;
}
}
.file-btn {
cursor: pointer;
}
input[type="file"] {
display: none;
}
.el-icon-plus {
span {
vertical-align: bottom;
font-size: 20px;
}
}
.loading {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5) url("../../image/loading.gif") no-repeat center center;
background-size: 25px 25px;
}
</style>
根据项目需要封装