|
|
@@ -1,18 +1,47 @@
|
|
|
<template>
|
|
|
<el-upload
|
|
|
- class="upload-demo"
|
|
|
+ class="file-upload"
|
|
|
:action="uploadUrl"
|
|
|
:on-success="onSuccess"
|
|
|
:on-remove="onRemove"
|
|
|
:headers="headers"
|
|
|
:file-list="fileList"
|
|
|
+ :limit="filesLimit"
|
|
|
+ :on-exceed="onExceed"
|
|
|
+ :on-preview="onPreview"
|
|
|
+ ref="upload"
|
|
|
>
|
|
|
- <el-button type="primary" :disabled="!(!single || fileList.length === 0)" size="mini">点击上传 </el-button>
|
|
|
+ <el-button type="primary" size="mini" slot="trigger">
|
|
|
+ 点击上传
|
|
|
+ </el-button>
|
|
|
+ <div class="file-list-item" slot="file" slot-scope="{ file }">
|
|
|
+ <div class="file-name">
|
|
|
+ <i class="status-icon el-icon-warning-outline danger" v-if="file.status === 'fail'"></i>
|
|
|
+ <i class="status-icon el-icon-circle-check success" v-else-if="file.status === 'success'"></i>
|
|
|
+ <i class="status-icon el-icon-loading" v-else></i>
|
|
|
+ {{ file.name }}
|
|
|
+ <i class="opt">
|
|
|
+ <i class="opt-icon el-icon-search" v-if="file.status === 'success'" @click="preview(file)"></i>
|
|
|
+ <i class="opt-icon el-icon-download" v-if="file.status === 'success'" @click="download(file)"></i>
|
|
|
+ <i class="opt-icon el-icon-delete" @click="removeFile(file)"></i>
|
|
|
+ </i>
|
|
|
+ </div>
|
|
|
+ <el-progress
|
|
|
+ v-if="file.status === 'uploading'"
|
|
|
+ :percentage="file.percentage"
|
|
|
+ :show-text="false"
|
|
|
+ :stroke-width="2"
|
|
|
+ class="upload-progress"
|
|
|
+ ></el-progress>
|
|
|
+ </div>
|
|
|
+ <el-image style="width:0;height:0;" :src="previewUrl" :preview-src-list="[previewUrl]" ref="preview">
|
|
|
+ </el-image>
|
|
|
</el-upload>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import resolveUrl from 'resolve-url';
|
|
|
+import axios from 'axios';
|
|
|
export default {
|
|
|
name: 'FileUpload',
|
|
|
props: {
|
|
|
@@ -22,13 +51,20 @@ export default {
|
|
|
return false;
|
|
|
}
|
|
|
},
|
|
|
+ limit: {
|
|
|
+ type: Number,
|
|
|
+ default() {
|
|
|
+ return 10000;
|
|
|
+ }
|
|
|
+ },
|
|
|
value: {}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
fileList: [],
|
|
|
watchValue: true,
|
|
|
- uploadUrl: ''
|
|
|
+ uploadUrl: '',
|
|
|
+ previewUrl: null
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
@@ -36,6 +72,15 @@ export default {
|
|
|
return {
|
|
|
Authorization: 'Bearer ' + localStorage.getItem('token')
|
|
|
};
|
|
|
+ },
|
|
|
+ filesLimit() {
|
|
|
+ if (this.single) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return this.limit;
|
|
|
+ },
|
|
|
+ disabled() {
|
|
|
+ return this.fileList.length >= this.limit;
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
@@ -51,7 +96,7 @@ export default {
|
|
|
this.fileList = fileList;
|
|
|
},
|
|
|
update(value) {
|
|
|
- if (this.single) {
|
|
|
+ if (this.filesLimit === 1) {
|
|
|
this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
|
|
|
} else {
|
|
|
if (!value) {
|
|
|
@@ -62,6 +107,35 @@ export default {
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
+ },
|
|
|
+ onExceed(files, fileList) {
|
|
|
+ console.log(files, fileList);
|
|
|
+ this.$message.error(`最多上传${this.filesLimit}个文件`);
|
|
|
+ },
|
|
|
+ onPreview(file) {
|
|
|
+ console.log(file);
|
|
|
+ },
|
|
|
+ removeFile(file) {
|
|
|
+ if (file.status === 'uploading') {
|
|
|
+ this.$refs.upload.abort(file);
|
|
|
+ } else if (file.status === 'success') {
|
|
|
+ let index = this.fileList.findIndex(i => i.url === file.url);
|
|
|
+ if (index > -1) {
|
|
|
+ this.fileList.splice(index, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ download(file) {
|
|
|
+ window.open(file.url, '_blank');
|
|
|
+ },
|
|
|
+ preview(file) {
|
|
|
+ this.previewUrl = file.url;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.preview.clickHandler();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ isImage(file) {
|
|
|
+ return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.url);
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
@@ -72,7 +146,7 @@ export default {
|
|
|
},
|
|
|
fileList(fileList) {
|
|
|
this.watchValue = false;
|
|
|
- if (this.single) {
|
|
|
+ if (this.filesLimit === 1) {
|
|
|
this.$emit('input', fileList[0] ? fileList[0].url : null);
|
|
|
} else {
|
|
|
this.$emit(
|
|
|
@@ -88,4 +162,46 @@ export default {
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
-<style scoped></style>
|
|
|
+<style lang="less" scoped>
|
|
|
+.file-list-item {
|
|
|
+ line-height: 1.8;
|
|
|
+ margin-top: 5px;
|
|
|
+ cursor: pointer;
|
|
|
+ .file-name {
|
|
|
+ padding: 0 90px 0 20px;
|
|
|
+ }
|
|
|
+ .upload-progress {
|
|
|
+ margin-top: 2px;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 20px;
|
|
|
+ right: 0;
|
|
|
+ width: auto;
|
|
|
+ }
|
|
|
+ .danger {
|
|
|
+ color: #f56c6c;
|
|
|
+ }
|
|
|
+ .success {
|
|
|
+ color: #67c23a;
|
|
|
+ }
|
|
|
+ .status-icon {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ line-height: inherit;
|
|
|
+ }
|
|
|
+ .opt {
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ line-height: inherit;
|
|
|
+ .opt-icon {
|
|
|
+ margin-left: 15px;
|
|
|
+ transition: color 0.3s;
|
|
|
+ &:hover {
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|