element/packages/upload/src/upload.vue

249 lines
6.9 KiB
Vue
Raw Normal View History

2016-07-27 06:15:02 +00:00
<template>
<div class="el-upload">
<!-- 选择类型 -->
<template v-if="type === 'select'">
<ul class="el-upload__files" v-show="showUploadList && uploadedFiles.length > 0" transition="slide-in-bottom">
<li class="el-upload__file" v-for="file in uploadedFiles" transition="slide-in-bottom">
<i class="el-icon-document"></i>{{file.name}}
<i class="el-icon-check" v-show="file.status === 'success'"></i>
<span class="el-upload__btn-delete" @click="removeFile(file)" v-show="file.status === 'finished'"></span>
<el-progress
v-if="file.status === 'success' || file.status === 'uploading'"
size="small"
:percentage="file.percentage"
:type="file.status === 'success' ? 'green' : 'blue'">
</el-progress>
</li>
</ul>
<component :is="uploadComponent"
:action="action",
:multiple="multiple",
:with-credentials="withCredentials",
:name="name",
:accept="accept",
:on-start="onStart",
:on-progress="onProgress",
:on-success="onSuccess",
:on-error="onError"
>
<slot></slot>
</component>
<slot name="tip"></slot>
</template>
<!-- 拖拽类型 -->
<template v-if="type === 'drag'">
<div class="el-dragger"
:class="{
'is-dragOver': dragOver,
'is-draging': draging,
'is-hover': mouseover,
'is-showImage': showImageBlock
}"
@drop.prevent="dragOver = false"
@dragOver.prevent="dragOver = true"
@dragLeave.prevent="dragOver = false"
@mouseenter="mouseover = true"
@mouseleave="mouseover = false"
>
<el-progress
class="el-dragger__progress"
v-if="mode === 'image' && (image.status === 'success' || image.status === 'uploading')"
size="large"
:percentage="image.percentage"
:type="image.status === 'success' ? 'green' : 'blue'">
</el-progress>
<div class="el-dragger__uploaded-image"
v-if="mode === 'image' && image.status === 'finished'"
transition="slide-in-bottom"
>
<img :src="image.url">
<div v-show="mouseover" class="el-dragger__uploaded-image__interact" transition="fade-in">
<slot name="interact"></slot>
</div>
<h4 v-show="mouseover" class="el-dragger__uploaded-image__title" transition="slide-in-bottom">{{image.name}}</h4>
</div>
<component :is="uploadComponent"
:action="action",
:multiple="multiple",
:with-credentials="withCredentials",
:name="name",
:accept="accept",
:on-start="onStart",
:on-progress="onProgress",
:on-success="onSuccess",
:on-error="onError"
>
<slot></slot>
</component>
</div>
<slot name="tip" class="el-dragger__tip"></slot>
<ul class="el-upload__files"
v-if="mode !== 'image' && showUploadList"
v-show="uploadedFiles.length > 0"
transition="slide-in-bottom"
>
<li class="el-upload__file" v-for="file in uploadedFiles" transition="slide-in-bottom">
<i class="el-icon-document"></i>{{file.name}}
<i class="el-icon-check" v-show="file.status === 'success'"></i>
<span class="el-upload__btn-delete" @click="removeFile(file)" v-show="file.status === 'finished'"></span>
<el-progress
v-if="file.status === 'success' || file.status === 'uploading'"
size="small"
:percentage="file.percentage"
:type="file.status === 'success' ? 'green' : 'blue'">
</el-progress>
</li>
</ul>
</template>
</div>
</template>
<script>
import AjaxUpload from './ajax-upload';
import IframeUpload from './iframe-upload';
import ElProgress from 'packages/progress/index.js';
export default {
name: 'el-upload',
// extends: typeof FormData !== 'undefined' ? ajaxUpload : iframeUpload,
// extends: iframeUpload,
components: {
ElProgress,
AjaxUpload,
IframeUpload
},
props: {
action: {
type: String,
required: true
},
headers: {
type: Object,
default() {
return {
// 'Access-Control-Request-Methods': 'GET, PUT, POST, DELETE, OPTIONS',
// 'Access-Control-Request-Headers': 'Content-Type, Content-Range, Content-Disposition, Content-Description'
};
}
},
multiple: false,
name: {
type: String,
default: 'file'
},
withCredentials: {
type: Boolean,
default: false
},
showUploadList: {
type: Boolean,
default: true
},
accept: String,
type: {
type: String,
default: 'select'
},
mode: String
},
data() {
return {
uploading: false,
percentage: 0,
uploadedFiles: [],
filename: '',
success: false,
dragOver: false,
draging: false,
mouseover: false,
tempIndex: 1
};
},
computed: {
uploadComponent() {
return typeof FormData !== 'undefined' ? 'AjaxUpload' : 'IframeUpload';
},
image() {
return this.uploadedFiles.length > 0 ? this.uploadedFiles[this.uploadedFiles.length - 1] : {};
},
showImageBlock() {
return this.mode === 'image' && this.image.status && this.image.status !== 'fail';
}
},
ready() {
if (this.mode === 'image') {
this.accept = 'image/*';
}
},
methods: {
isImage(str) {
return str.indexOf('image') !== -1;
},
removeFile(file) {
this.uploadedFiles.$remove(file);
this.$dispatch('fileremove', file, this.uploadedFiles);
},
onStart(files) {
files.forEach(file => {
let isImage = this.isImage(file.type);
let uid = Date.now() + this.tempIndex++;
let _file = {
status: 'uploading',
name: file.name,
size: file.size,
percentage: 0,
uid: uid
};
if (this.mode === 'image') {
if (!isImage) {
this.tempIndex--;
return;
} else {
_file.url = URL.createObjectURL(file);
}
}
this.uploadedFiles.push(_file);
file.index = this.uploadedFiles.length - 1;
});
},
onProgress(ev, file) {
this.uploadedFiles[file.index].percentage = ev.percent;
},
onSuccess(res, file) {
var _file = this.uploadedFiles[file.index];
_file.status = 'success';
setTimeout(() => {
_file.status = 'finished';
this.reset();
}, 1000);
},
onError(err, file) {
var _file = this.uploadedFiles[file.index];
_file.status = 'finished';
this.uploadedFiles.$remove(_file);
this.reset();
console.log(err);
},
reset() {
this.uploading = false;
this.percent = 0;
this.filename = '';
}
}
};
</script>