Commit a90e1769 authored by baiyaaaaa's avatar baiyaaaaa Committed by GitHub

Merge pull request #82 from eleme/feat/upload

update upload
parents 019b325a 0aaf2df4
......@@ -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 |
@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;
}
.slide-in-bottom-leave {
animation: slideInBottomLeave .3s;
}
@keyframes slideInBottomEnter {
0% {
opacity: 0;
transform: translate3d(0,50%,0);
}
.list-move, .list-enter-active, .list-leave-active {
transition: all .5s cubic-bezier(.55,0,.1,1);
}
@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 {
......
const Upload = require('./src/upload');
const Upload = require('./src/index');
Upload.install = function(Vue) {
Vue.component(Upload.name, Upload);
......
<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>
<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>
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment