mirror of https://github.com/ElemeFE/element
update upload
parent
2ceff8709e
commit
0aaf2df436
|
@ -7,33 +7,6 @@
|
|||
.demo-box {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.el-draggeer__uploaded-image__btns {
|
||||
margin-top: 45px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
|
||||
& .btn {
|
||||
display: inline-block;
|
||||
|
||||
& span {
|
||||
opacity: 0;
|
||||
transition: opacity .15s linear;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 35px;
|
||||
}
|
||||
|
||||
&:hover span {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
& i {
|
||||
display: block;
|
||||
font-size: 26px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
export default {
|
||||
|
@ -43,6 +16,16 @@
|
|||
},
|
||||
handleRemove(file, fileList) {
|
||||
console.log(file, fileList);
|
||||
},
|
||||
beforeUpload(file) {
|
||||
if (file.size > 40000000) {
|
||||
console.warn(file.name + ' is too large!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
handlePreview(file) {
|
||||
console.log(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,31 +34,66 @@
|
|||
## 基础使用
|
||||
|
||||
<div class="demo-box">
|
||||
<el-upload action="http://127.0.0.1:9000/upload" @filechange="handleChange" @fileremove="handleRemove">
|
||||
<el-upload action="http://element.alpha.elenet.me/upload" :on-preview="handlePreview" :on-remove="handleRemove">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<el-upload action="http://127.0.0.1:9000/upload" @filechange="handleChange" @fileremove="handleRemove">
|
||||
<el-upload action="http://element.alpha.elenet.me/upload" :on-preview="handlePreview" :on-remove="handleRemove">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleRemove(file, fileList) {
|
||||
console.log(file, fileList);
|
||||
},
|
||||
handlePreview(file) {
|
||||
console.log(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 拖拽文件上传
|
||||
|
||||
<div class="demo-box">
|
||||
<el-upload action="http://127.0.0.1:9000/upload" type="drag" :multiple="true">
|
||||
<el-upload
|
||||
action="http://element.alpha.elenet.me/upload"
|
||||
type="drag"
|
||||
:multiple="true"
|
||||
:on-preview="handlePreview"
|
||||
:on-remove="handleRemove">
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<el-upload action="http://127.0.0.1:9000/upload" type="drag" :multiple="true">
|
||||
<el-upload
|
||||
action="http://element.alpha.elenet.me/upload"
|
||||
type="drag"
|
||||
:multiple="true"
|
||||
:on-preview="handlePreview"
|
||||
:on-remove="handleRemove">
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleRemove(file, fileList) {
|
||||
console.log(file, fileList);
|
||||
},
|
||||
handlePreview(file) {
|
||||
console.log(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 图片缩略图模式
|
||||
|
@ -83,23 +101,39 @@
|
|||
上传文件类型限制为只能上传图片,并可展示本地缩略图,该模式暂不支持多选
|
||||
|
||||
<div class="demo-box">
|
||||
<el-upload action="http://127.0.0.1:9000/upload" type="drag" mode="image">
|
||||
<div class="el-draggeer__uploaded-image__btns" slot="interact">
|
||||
<span class="btn"><i class="el-icon-share"></i><span>分享图片</span></span>
|
||||
<span class="btn"><i class="el-icon-delete"></i><span>删除</span></span>
|
||||
</div>
|
||||
<el-upload
|
||||
action="http://element.alpha.elenet.me/upload"
|
||||
type="drag"
|
||||
:thumbnail-mode="true"
|
||||
:on-preview="handlePreview"
|
||||
:on-remove="handleRemove"
|
||||
>
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
|
||||
```html
|
||||
<el-upload action="http://127.0.0.1:9000/upload" type="drag" mode="image">
|
||||
<div class="el-draggeer__uploaded-image__btns" slot="interact">
|
||||
<span class="btn"><i class="el-icon-share"></i><span>分享图片</span></span>
|
||||
<span class="btn"><i class="el-icon-delete"></i><span>删除</span></span>
|
||||
</div>
|
||||
<el-upload
|
||||
action="http://element.alpha.elenet.me/upload"
|
||||
type="drag"
|
||||
:thumbnail-mode="true"
|
||||
:on-preview="handlePreview"
|
||||
:on-remove="handleRemove"
|
||||
>
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleRemove(file, fileList) {
|
||||
console.log(file, fileList);
|
||||
},
|
||||
handlePreview(file) {
|
||||
console.log(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## API
|
||||
|
@ -113,6 +147,8 @@
|
|||
| showUploadList | 是否显示已上传文件列表 | boolean | | true |
|
||||
| type | 上传控件类型 | string | select,drag | select |
|
||||
| accept | 可选参数, 接受上传的[文件类型](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept), 拖拽文件上传时不受此参数影响 | string | | |
|
||||
| filechange | 可选参数, 上传文件改变时的回调 | function(file, fileList, event) | | |
|
||||
| fileremove | 可选参数, 文件列表移除文件时的回调 | function(file, fileList) | | |
|
||||
| onPreview | 可选参数, 点击已上传的文件链接时的钩子 | function(file) | | |
|
||||
| onRemove | 可选参数, 文件列表移除文件时的钩子 | function(file, fileList) | | |
|
||||
| beforeUpload | 可选参数, 上传文件之前的钩子,参数为上传的文件,若返回 false 或者 Promise 则停止上传。 | function(file) | | |
|
||||
| thumbnailMode | 是否设置为图片模式,该模式下会显示图片缩略图 | boolean | | false |
|
||||
| type | 上传控件类型 | string | select,drag | select |
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
@charset "UTF-8";
|
||||
@import './var.css';
|
||||
|
||||
.fade-in-transition {
|
||||
opacity: 1;
|
||||
transition: var(--fade-transition);
|
||||
}
|
||||
|
||||
.fade-in-linear-enter-active {
|
||||
opacity: 1;
|
||||
.fade-in-linear-enter-active,
|
||||
.fade-in-linear-leave-active {
|
||||
transition: var(--fade-linear-transition);
|
||||
}
|
||||
|
||||
.fade-in-linear-enter,
|
||||
.fade-in-linear-leave,
|
||||
.fade-in-linear-leave-active {
|
||||
opacity: 0;
|
||||
transition: var(--fade-linear-transition);
|
||||
}
|
||||
|
||||
.fade-in-enter-active,
|
||||
.fade-in-leave-active {
|
||||
transition: all .3s cubic-bezier(.55,0,.1,1);
|
||||
}
|
||||
|
||||
.fade-in-enter,
|
||||
.fade-in-leave,
|
||||
.fade-in-linear-enter,
|
||||
.fade-in-linear-leave {
|
||||
.fade-in-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
@ -96,28 +95,19 @@
|
|||
transition: opacity .3s cubic-bezier(.645,.045,.355,1);
|
||||
}
|
||||
.fade-enter,
|
||||
.fade-leave,
|
||||
.fade-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-in-bottom-enter {
|
||||
animation: slideInBottomEnter .3s;
|
||||
.list-move, .list-enter-active, .list-leave-active {
|
||||
transition: all .5s cubic-bezier(.55,0,.1,1);
|
||||
}
|
||||
.slide-in-bottom-leave {
|
||||
animation: slideInBottomLeave .3s;
|
||||
}
|
||||
|
||||
@keyframes slideInBottomEnter {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translate3d(0,50%,0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInBottomLeave {
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translate3d(0,50%,0);
|
||||
}
|
||||
.list-enter, .list-leave-active {
|
||||
opacity: 0;
|
||||
transform: translate(0, -30px);
|
||||
}
|
||||
/*.list-leave-active {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
transform: scaleY(0.01) translate(30px, 0);
|
||||
}*/
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
--color-black: #000;
|
||||
--color-grey: #C0CCDA;
|
||||
|
||||
/* Link
|
||||
-------------------------- */
|
||||
--link-color: #475669;
|
||||
--link-hover-color: var(--color-primary);
|
||||
|
||||
/* Border
|
||||
-------------------------- */
|
||||
--border-width-base: 1px;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
@e file {
|
||||
transition: all .5s cubic-bezier(.55,0,.1,1);
|
||||
font-size: 14px;
|
||||
color: #475669;
|
||||
line-height: 32px;
|
||||
|
@ -33,21 +34,16 @@
|
|||
text-overflow: ellipsis;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
color: #475669;
|
||||
transition: color .3s;
|
||||
}
|
||||
[class^="el-icon"] {
|
||||
color: #99a9bf;
|
||||
margin-right: 7px;
|
||||
height: 100%;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #eff2f7;
|
||||
|
||||
.el-upload__btn-delete {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
& .el-progress {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
@ -61,6 +57,21 @@
|
|||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #eff2f7;
|
||||
}
|
||||
@when finished {
|
||||
& a:hover {
|
||||
color: var(--link-hover-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
&:hover {
|
||||
.el-upload__btn-delete {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@e tip {
|
||||
font-size: 12px;
|
||||
|
@ -125,6 +136,7 @@
|
|||
height: 100%;
|
||||
overflow: hidden;
|
||||
z-index: 10;
|
||||
cursor: default;
|
||||
|
||||
& img {
|
||||
display: block;
|
||||
|
@ -140,6 +152,45 @@
|
|||
height: 100%;
|
||||
background-color: rgba(#000, .72);
|
||||
text-align: center;
|
||||
|
||||
& .btn {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
transition: var(--md-fade-transition);
|
||||
margin-top: 60px;
|
||||
|
||||
& i {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
& span {
|
||||
opacity: 0;
|
||||
transition: opacity .15s linear;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 35px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-13px);
|
||||
|
||||
& span {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
& i {
|
||||
color: #fff;
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
line-height: inherit;
|
||||
margin: 0 auto 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@e title {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const Upload = require('./src/upload');
|
||||
const Upload = require('./src/index');
|
||||
|
||||
Upload.install = function(Vue) {
|
||||
Vue.component(Upload.name, Upload);
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
<script>
|
||||
import UploadList from './upload-list';
|
||||
import Upload from './upload';
|
||||
import ElProgress from 'packages/progress/index.js';
|
||||
|
||||
function noop() {
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'el-upload',
|
||||
|
||||
// extends: typeof FormData !== 'undefined' ? ajaxUpload : iframeUpload,
|
||||
// extends: iframeUpload,
|
||||
|
||||
components: {
|
||||
ElProgress,
|
||||
UploadList,
|
||||
Upload
|
||||
},
|
||||
|
||||
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: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: 'file'
|
||||
},
|
||||
withCredentials: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
thumbnailMode: Boolean,
|
||||
showUploadList: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
accept: String,
|
||||
type: {
|
||||
type: String,
|
||||
default: 'select'
|
||||
},
|
||||
beforeUpload: Function,
|
||||
onRemove: {
|
||||
type: Function,
|
||||
default: noop
|
||||
},
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: noop
|
||||
},
|
||||
onPreview: {
|
||||
type: Function,
|
||||
default: noop
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
uploadedFiles: [],
|
||||
dragOver: false,
|
||||
draging: false,
|
||||
tempIndex: 1
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onStart(file) {
|
||||
file.uid = Date.now() + this.tempIndex++;
|
||||
let _file = {
|
||||
status: 'uploading',
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
percentage: 0,
|
||||
uid: file.uid,
|
||||
showProgress: true
|
||||
};
|
||||
|
||||
if (this.thumbnailMode) {
|
||||
try {
|
||||
_file.url = URL.createObjectURL(file);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.uploadedFiles.push(_file);
|
||||
},
|
||||
onProgress(ev, file) {
|
||||
var _file = this.getFile(file);
|
||||
_file.percentage = ev.percent;
|
||||
},
|
||||
onSuccess(res, file) {
|
||||
var _file = this.getFile(file);
|
||||
|
||||
_file.status = 'finished';
|
||||
_file.response = res;
|
||||
|
||||
setTimeout(() => {
|
||||
_file.showProgress = false;
|
||||
}, 1000);
|
||||
},
|
||||
onError(err, file) {
|
||||
var _file = this.getFile(file);
|
||||
var fileList = this.uploadedFiles;
|
||||
|
||||
_file.status = 'fail';
|
||||
|
||||
fileList.splice(fileList.indexOf(_file), 1);
|
||||
this.$emit('error', _file, fileList, err);
|
||||
},
|
||||
handleRemove(file) {
|
||||
var fileList = this.uploadedFiles;
|
||||
fileList.splice(fileList.indexOf(file), 1);
|
||||
this.onRemove(file, fileList);
|
||||
},
|
||||
getFile(file) {
|
||||
var fileList = this.uploadedFiles;
|
||||
var target;
|
||||
fileList.every(item => {
|
||||
target = file.uid === item.uid ? item : null;
|
||||
return !target;
|
||||
});
|
||||
return target;
|
||||
},
|
||||
handlePreview(file) {
|
||||
if (file.status === 'finished') {
|
||||
this.onPreview(file);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render(h) {
|
||||
var uploadList;
|
||||
if (this.showUploadList && !this.thumbnailMode) {
|
||||
uploadList = (
|
||||
<UploadList
|
||||
files={this.uploadedFiles}
|
||||
on-remove={this.handleRemove}
|
||||
on-preview={this.handlePreview}>
|
||||
</UploadList>
|
||||
);
|
||||
}
|
||||
|
||||
var props = {
|
||||
props: {
|
||||
action: this.action,
|
||||
multiple: this.multiple,
|
||||
'before-upload': this.beforeUpload,
|
||||
'with-credentials': this.withCredentials,
|
||||
name: this.name,
|
||||
accept: this.thumbnailMode ? 'image/*' : this.accept,
|
||||
'on-start': this.onStart,
|
||||
'on-progress': this.onProgress,
|
||||
'on-success': this.onSuccess,
|
||||
'on-error': this.onError,
|
||||
'on-preview': this.handlePreview,
|
||||
'on-remove': this.handleRemove
|
||||
}
|
||||
};
|
||||
|
||||
if (this.type === 'select') {
|
||||
return (
|
||||
<div class="el-upload">
|
||||
{uploadList}
|
||||
<upload {...props}>
|
||||
{this.$slots.default}
|
||||
</upload>
|
||||
{this.$slots.tip}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.type === 'drag') {
|
||||
props.props.type = 'drag';
|
||||
|
||||
return (
|
||||
<div class="el-upload">
|
||||
<upload {...props}>
|
||||
{this.$slots.default}
|
||||
</upload>
|
||||
{this.$slots.tip}
|
||||
{uploadList}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<transition-group tag="ul" class="el-upload__files" name="list">
|
||||
<li
|
||||
v-for="file in files"
|
||||
class="el-upload__file"
|
||||
:class="{
|
||||
'is-finished': file.status === 'finished'
|
||||
}"
|
||||
:key="file"
|
||||
@click="$emit('clickFile', file)"
|
||||
>
|
||||
<a class="el-upload__file__name" @click="$emit('preview', file)">
|
||||
<i class="el-icon-document"></i>{{file.name}}
|
||||
</a>
|
||||
<i class="el-icon-check" v-if="file.status === 'finished' && file.showProgress"></i>
|
||||
<span class="el-upload__btn-delete" @click="$emit('remove', file)" v-show="file.status === 'finished'">删除</span>
|
||||
<el-progress
|
||||
v-if="file.showProgress"
|
||||
size="small"
|
||||
:percentage="file.percentage"
|
||||
:type="file.status === 'finished' ? 'green' : 'blue'">
|
||||
</el-progress>
|
||||
</li>
|
||||
</transition-group>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
files: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -1,187 +1,103 @@
|
|||
<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>
|
||||
<div class="el-upload__inner"
|
||||
:class="{
|
||||
'el-dragger': type === 'drag',
|
||||
'is-dragOver': dragOver,
|
||||
'is-hover': mouseover,
|
||||
'is-showImage': showThumbnail
|
||||
}"
|
||||
@click="$refs.input.click()"
|
||||
@drop.prevent="onDrop"
|
||||
@dragover.prevent="dragOver = true"
|
||||
@dragleave.prevent="dragOver = false"
|
||||
@mouseenter="mouseover = true"
|
||||
@mouseleave="mouseover = false"
|
||||
>
|
||||
<slot></slot>
|
||||
<template v-if="type === 'drag' && !showThumbnail">
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-dragger__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
</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"
|
||||
>
|
||||
<template v-if="thumbnailMode">
|
||||
<transition name="fade-in">
|
||||
<el-progress
|
||||
class="el-dragger__progress"
|
||||
v-if="mode === 'image' && (image.status === 'success' || image.status === 'uploading')"
|
||||
v-if="lastestFile.showProgress"
|
||||
size="large"
|
||||
:percentage="image.percentage"
|
||||
:type="image.status === 'success' ? 'green' : 'blue'">
|
||||
:percentage="lastestFile.percentage"
|
||||
:type="lastestFile.status === 'finished' ? '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>
|
||||
</transition>
|
||||
<div class="el-dragger__uploaded-image" v-if="lastestFile.status === 'finished'" @click.stop>
|
||||
<img :src="lastestFile.url">
|
||||
<transition name="fade-in">
|
||||
<div v-show="mouseover" class="el-dragger__uploaded-image__interact">
|
||||
<div class="el-draggeer__uploaded-image__btns">
|
||||
<span class="btn" @click="$refs.input.click()"><i class="el-icon-upload"></i><span>继续上传</span></span>
|
||||
<span class="btn" @click="onPreview(lastestFile)"><i class="el-icon-search"></i><span>查看图片</span></span>
|
||||
<span class="btn" @click="onRemove(lastestFile)"><i class="el-icon-delete"></i><span>删除</span></span>
|
||||
</div>
|
||||
</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>
|
||||
</transition>
|
||||
<transition name="md-fade-top">
|
||||
<h4 v-show="mouseover" class="el-dragger__uploaded-image__title">{{lastestFile.name}}</h4>
|
||||
</transition>
|
||||
</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>
|
||||
<input class="el-upload__input" type="file" ref="input" @change="handleChange" :multiple="multiple" :accept="accept">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AjaxUpload from './ajax-upload';
|
||||
import IframeUpload from './iframe-upload';
|
||||
import ElProgress from 'packages/progress/index.js';
|
||||
import ajax from './ajax';
|
||||
|
||||
export default {
|
||||
name: 'el-upload',
|
||||
|
||||
// extends: typeof FormData !== 'undefined' ? ajaxUpload : iframeUpload,
|
||||
// extends: iframeUpload,
|
||||
|
||||
components: {
|
||||
ElProgress,
|
||||
AjaxUpload,
|
||||
IframeUpload
|
||||
},
|
||||
|
||||
props: {
|
||||
type: String,
|
||||
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
|
||||
},
|
||||
withCredentials: Boolean,
|
||||
multiple: Boolean,
|
||||
accept: String,
|
||||
type: {
|
||||
type: String,
|
||||
default: 'select'
|
||||
onStart: Function,
|
||||
onProgress: Function,
|
||||
onSuccess: Function,
|
||||
onError: Function,
|
||||
beforeUpload: Function,
|
||||
onPreview: {
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
mode: String
|
||||
onRemove: {
|
||||
type: Function,
|
||||
default: function() {}
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
uploading: false,
|
||||
percentage: 0,
|
||||
uploadedFiles: [],
|
||||
filename: '',
|
||||
success: false,
|
||||
dragOver: false,
|
||||
draging: false,
|
||||
mouseover: false,
|
||||
tempIndex: 1
|
||||
mouseover: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
uploadComponent() {
|
||||
return typeof FormData !== 'undefined' ? 'AjaxUpload' : 'IframeUpload';
|
||||
lastestFile() {
|
||||
var uploadedFiles = this.$parent.uploadedFiles;
|
||||
return uploadedFiles.length > 0 ? uploadedFiles[uploadedFiles.length - 1] : {};
|
||||
},
|
||||
image() {
|
||||
return this.uploadedFiles.length > 0 ? this.uploadedFiles[this.uploadedFiles.length - 1] : {};
|
||||
showThumbnail() {
|
||||
var file = this.lastestFile;
|
||||
return this.thumbnailMode && file.status && file.status !== 'fail';
|
||||
},
|
||||
showImageBlock() {
|
||||
return this.mode === 'image' && this.image.status && this.image.status !== 'fail';
|
||||
}
|
||||
},
|
||||
|
||||
ready() {
|
||||
if (this.mode === 'image') {
|
||||
this.accept = 'image/*';
|
||||
thumbnailMode() {
|
||||
return this.$parent.thumbnailMode;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -189,59 +105,76 @@ export default {
|
|||
isImage(str) {
|
||||
return str.indexOf('image') !== -1;
|
||||
},
|
||||
removeFile(file) {
|
||||
this.uploadedFiles.$remove(file);
|
||||
this.$dispatch('fileremove', file, this.uploadedFiles);
|
||||
handleChange(ev) {
|
||||
const files = ev.target.files;
|
||||
|
||||
if (!files) {
|
||||
return;
|
||||
}
|
||||
this.uploadFiles(files);
|
||||
},
|
||||
onStart(files) {
|
||||
files.forEach(file => {
|
||||
uploadFiles(files) {
|
||||
let postFiles = Array.prototype.slice.call(files);
|
||||
if (!this.multiple) { postFiles = postFiles.slice(0, 1); }
|
||||
|
||||
if (postFiles.length === 0) { return; }
|
||||
|
||||
postFiles.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);
|
||||
}
|
||||
|
||||
if (this.thumbnailMode && !isImage) {
|
||||
return;
|
||||
} else {
|
||||
this.upload(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];
|
||||
upload(file) {
|
||||
if (!this.beforeUpload) {
|
||||
return this.post(file);
|
||||
}
|
||||
|
||||
_file.status = 'success';
|
||||
setTimeout(() => {
|
||||
_file.status = 'finished';
|
||||
this.reset();
|
||||
}, 1000);
|
||||
const before = this.beforeUpload(file);
|
||||
if (before && before.then) {
|
||||
before.then(processedFile => {
|
||||
if (Object.prototype.toString.call(processedFile) === '[object File]') {
|
||||
this.post(processedFile);
|
||||
} else {
|
||||
this.post(file);
|
||||
}
|
||||
}, () => {
|
||||
// this.$emit('cancel', file);
|
||||
});
|
||||
} else if (before !== false) {
|
||||
this.post(file);
|
||||
} else {
|
||||
// this.$emit('cancel', file);
|
||||
}
|
||||
},
|
||||
onError(err, file) {
|
||||
var _file = this.uploadedFiles[file.index];
|
||||
post(file) {
|
||||
this.onStart(file);
|
||||
let formData = new FormData();
|
||||
formData.append(this.name, file);
|
||||
|
||||
_file.status = 'finished';
|
||||
this.uploadedFiles.$remove(_file);
|
||||
this.reset();
|
||||
console.log(err);
|
||||
ajax(this.action, {
|
||||
headers: this.headers,
|
||||
withCredentials: this.withCredentials,
|
||||
file: file,
|
||||
filename: this.name,
|
||||
onProgress: e => {
|
||||
this.onProgress(e, file);
|
||||
},
|
||||
onSuccess: res => {
|
||||
this.onSuccess(res, file);
|
||||
},
|
||||
onError: err => {
|
||||
this.onError(err, file);
|
||||
}
|
||||
});
|
||||
},
|
||||
reset() {
|
||||
this.uploading = false;
|
||||
this.percent = 0;
|
||||
this.filename = '';
|
||||
onDrop(e) {
|
||||
this.dragOver = false;
|
||||
this.uploadFiles(e.dataTransfer.files);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue