Commit ddef2bb3d6599f5a224b5238ac60efb01f3902d3
1 parent
1992733e
update Upload
update Upload
Showing
4 changed files
with
226 additions
and
23 deletions
Show diff stats
src/components/upload/upload-list.vue
| 1 | 1 | <template> |
| 2 | - | |
| 2 | + <ul :class="[prefixCls + '-list']"> | |
| 3 | + <li | |
| 4 | + v-for="file in files" | |
| 5 | + :class="fileCls(file)" | |
| 6 | + @click="handleClick(file)"> | |
| 7 | + <span @click="handlePreview(file)"> | |
| 8 | + <Icon :type="format(file)"></Icon> {{ file.name }} | |
| 9 | + </span> | |
| 10 | + <Icon | |
| 11 | + type="ios-close-empty" | |
| 12 | + :class="[prefixCls + '-list-remove']" | |
| 13 | + v-show="file.status === 'finished'" | |
| 14 | + @click="handleRemove(file)"></Icon> | |
| 15 | + <Progress | |
| 16 | + v-if="file.showProgress" | |
| 17 | + :stroke-width="2" | |
| 18 | + :percent="parsePercentage(file.percentage)" | |
| 19 | + :status="file.status === 'finished' && file.showProgress ? 'success' : 'normal'" | |
| 20 | + transition="fade"></Progress> | |
| 21 | + </li> | |
| 22 | + </ul> | |
| 3 | 23 | </template> |
| 4 | 24 | <script> |
| 25 | + import Icon from '../icon/icon.vue'; | |
| 26 | + import Progress from '../progress/progress.vue'; | |
| 27 | + const prefixCls = 'ivu-upload'; | |
| 28 | + | |
| 5 | 29 | export default { |
| 6 | - props: {}, | |
| 30 | + components: { Icon, Progress }, | |
| 31 | + props: { | |
| 32 | + files: { | |
| 33 | + type: Array, | |
| 34 | + default() { | |
| 35 | + return []; | |
| 36 | + } | |
| 37 | + } | |
| 38 | + }, | |
| 7 | 39 | data () { |
| 8 | - return {}; | |
| 40 | + return { | |
| 41 | + prefixCls: prefixCls | |
| 42 | + }; | |
| 9 | 43 | }, |
| 10 | 44 | computed: {}, |
| 11 | - methods: {} | |
| 45 | + methods: { | |
| 46 | + fileCls (file) { | |
| 47 | + return [ | |
| 48 | + `${prefixCls}-list-file`, | |
| 49 | + { | |
| 50 | + [`${prefixCls}-list-file-finish`]: file.status === 'finished' | |
| 51 | + } | |
| 52 | + ]; | |
| 53 | + }, | |
| 54 | + handleClick (file) { | |
| 55 | + this.$emit('on-file-click', file); | |
| 56 | + }, | |
| 57 | + handlePreview (file) { | |
| 58 | + this.$emit('on-file-preview', file); | |
| 59 | + }, | |
| 60 | + handleRemove (file) { | |
| 61 | + this.$emit('on-file-remove', file); | |
| 62 | + }, | |
| 63 | + format (file) { | |
| 64 | + const format = file.name.split('.').pop().toLocaleLowerCase() || ''; | |
| 65 | + let type = 'document'; | |
| 66 | + | |
| 67 | + if (['gif','jpg','jpeg','png','bmp','webp'].indexOf(format) > -1) { | |
| 68 | + type = 'image'; | |
| 69 | + } | |
| 70 | + if (['mp4','m3u8','rmvb','avi','swf','3gp','mkv','flv'].indexOf(format) > -1) { | |
| 71 | + type = 'ios-film'; | |
| 72 | + } | |
| 73 | + if (['mp3','wav','wma','ogg','aac','flac'].indexOf(format) > -1) { | |
| 74 | + type = 'ios-musical-notes'; | |
| 75 | + } | |
| 76 | + if (['doc','txt','docx','pages','epub','pdf'].indexOf(format) > -1) { | |
| 77 | + type = 'document-text'; | |
| 78 | + } | |
| 79 | + if (['numbers','csv','xls','xlsx'].indexOf(format) > -1) { | |
| 80 | + type = 'stats-bars'; | |
| 81 | + } | |
| 82 | + if (['keynote','ppt','pptx'].indexOf(format) > -1) { | |
| 83 | + type = 'ios-videocam'; | |
| 84 | + } | |
| 85 | + | |
| 86 | + return type; | |
| 87 | + }, | |
| 88 | + parsePercentage (val) { | |
| 89 | + return parseInt(val, 10); | |
| 90 | + } | |
| 91 | + } | |
| 12 | 92 | }; |
| 13 | 93 | </script> |
| 14 | 94 | \ No newline at end of file | ... | ... |
src/components/upload/upload.vue
| 1 | 1 | <template> |
| 2 | - <div | |
| 3 | - :class="classes" | |
| 4 | - @click="handleClick" | |
| 5 | - @drop.prevent="onDrop" | |
| 6 | - @dragover.prevent="dragOver = true" | |
| 7 | - @dragleave.prevent="dragOver = false"> | |
| 8 | - <input | |
| 9 | - v-el:input | |
| 10 | - :class="[prefixCls + '-input']" | |
| 11 | - type="file" | |
| 12 | - @change="handleChange" | |
| 13 | - :multiple="multiple" | |
| 14 | - :accept="accept"> | |
| 15 | - <slot></slot> | |
| 2 | + <div :class="[prefixCls]"> | |
| 3 | + <div | |
| 4 | + :class="classes" | |
| 5 | + @click="handleClick" | |
| 6 | + @drop.prevent="onDrop" | |
| 7 | + @dragover.prevent="dragOver = true" | |
| 8 | + @dragleave.prevent="dragOver = false"> | |
| 9 | + <input | |
| 10 | + v-el:input | |
| 11 | + :class="[prefixCls + '-input']" | |
| 12 | + type="file" | |
| 13 | + @change="handleChange" | |
| 14 | + :multiple="multiple" | |
| 15 | + :accept="accept"> | |
| 16 | + <slot></slot> | |
| 17 | + </div> | |
| 18 | + <slot name="tip"></slot> | |
| 19 | + <upload-list | |
| 20 | + v-if="showUploadList" | |
| 21 | + :files="fileList" | |
| 22 | + @on-file-remove="handleRemove" | |
| 23 | + @on-file-preview="handlePreview"></upload-list> | |
| 16 | 24 | </div> |
| 17 | 25 | </template> |
| 18 | 26 | <script> |
| 27 | + import UploadList from './upload-list.vue'; | |
| 19 | 28 | import ajax from './ajax'; |
| 20 | 29 | import { oneOf } from '../../utils/assist'; |
| 21 | 30 | |
| 22 | 31 | const prefixCls = 'ivu-upload'; |
| 23 | 32 | |
| 24 | 33 | export default { |
| 34 | + components: { UploadList }, | |
| 25 | 35 | props: { |
| 26 | 36 | action: { |
| 27 | 37 | type: String, |
| ... | ... | @@ -56,7 +66,8 @@ |
| 56 | 66 | type: String, |
| 57 | 67 | validator (value) { |
| 58 | 68 | return oneOf(value, ['select', 'drag']); |
| 59 | - } | |
| 69 | + }, | |
| 70 | + default: 'select' | |
| 60 | 71 | }, |
| 61 | 72 | format: { |
| 62 | 73 | type: Array, |
| ... | ... | @@ -133,6 +144,7 @@ |
| 133 | 144 | return [ |
| 134 | 145 | `${prefixCls}`, |
| 135 | 146 | { |
| 147 | + [`${prefixCls}-select`]: this.type === 'select', | |
| 136 | 148 | [`${prefixCls}-drag`]: this.type === 'drag', |
| 137 | 149 | [`${prefixCls}-dragOver`]: this.dragOver |
| 138 | 150 | } | ... | ... |
src/styles/components/upload.less
| 1 | 1 | @upload-prefix-cls: ~"@{css-prefix}upload"; |
| 2 | 2 | |
| 3 | 3 | .@{upload-prefix-cls} { |
| 4 | + input[type="file"]{ | |
| 5 | + display: none; | |
| 6 | + } | |
| 4 | 7 | |
| 8 | + &-list{ | |
| 9 | + margin-bottom: 8px; | |
| 10 | + | |
| 11 | + &-file{ | |
| 12 | + padding: 4px; | |
| 13 | + color: @text-color; | |
| 14 | + border-radius: @border-radius-small; | |
| 15 | + transition: background-color @transition-time @ease-in-out; | |
| 16 | + overflow: hidden; | |
| 17 | + position: relative; | |
| 18 | + | |
| 19 | + & + span{ | |
| 20 | + cursor: pointer; | |
| 21 | + transition: color @transition-time @ease-in-out; | |
| 22 | + i{ | |
| 23 | + display: inline-block; | |
| 24 | + width: @font-size-small; | |
| 25 | + height: @font-size-small; | |
| 26 | + color: @text-color; | |
| 27 | + text-align: center; | |
| 28 | + } | |
| 29 | + } | |
| 30 | + | |
| 31 | + &:hover{ | |
| 32 | + background: @input-disabled-bg; | |
| 33 | + & + span{ | |
| 34 | + color: @primary-color; | |
| 35 | + i{ | |
| 36 | + color: @text-color; | |
| 37 | + } | |
| 38 | + } | |
| 39 | + .@{upload-prefix-cls}-list-remove{ | |
| 40 | + opacity: 1; | |
| 41 | + } | |
| 42 | + } | |
| 43 | + } | |
| 44 | + &-remove{ | |
| 45 | + opacity: 0; | |
| 46 | + font-size: 18px; | |
| 47 | + cursor: pointer; | |
| 48 | + float: right; | |
| 49 | + margin-right: 4px; | |
| 50 | + color: @legend-color; | |
| 51 | + transition: all @transition-time ease; | |
| 52 | + &:hover{ | |
| 53 | + color: #444; | |
| 54 | + } | |
| 55 | + } | |
| 56 | + } | |
| 57 | + | |
| 58 | + &-drag{ | |
| 59 | + background: #fff; | |
| 60 | + border: 1px dashed @border-color-base; | |
| 61 | + border-radius: @border-radius-small; | |
| 62 | + text-align: center; | |
| 63 | + cursor: pointer; | |
| 64 | + position: relative; | |
| 65 | + overflow: hidden; | |
| 66 | + transition: border-color @transition-time ease; | |
| 67 | + | |
| 68 | + &:hover{ | |
| 69 | + border: 1px dashed @primary-color; | |
| 70 | + } | |
| 71 | + } | |
| 72 | + &-dragOver{ | |
| 73 | + border: 2px dashed @primary-color; | |
| 74 | + } | |
| 5 | 75 | } |
| 6 | 76 | \ No newline at end of file | ... | ... |
test/routers/upload.vue
| 1 | 1 | <template> |
| 2 | - <Upload action="/qiniu" :max-size="10000"> | |
| 3 | - <i-button>上传</i-button> | |
| 4 | - </Upload> | |
| 2 | + <div style="margin: 50px;width: 300px;"> | |
| 3 | + <Upload | |
| 4 | + action="//jsonplaceholder.typicode.com/posts/" | |
| 5 | + multiple | |
| 6 | + type="drag" | |
| 7 | + :max-size="10000" | |
| 8 | + :default-file-list="defaultFileList"> | |
| 9 | + <div style="padding: 40px 100px"> | |
| 10 | + <i-button>上传</i-button> | |
| 11 | + </div> | |
| 12 | + <!--<div slot="tip">只能上传 jpg/png 格式的文件</div>--> | |
| 13 | + </Upload> | |
| 14 | + </div> | |
| 5 | 15 | </template> |
| 6 | 16 | <script> |
| 7 | 17 | export default { |
| 8 | 18 | props: {}, |
| 9 | 19 | data () { |
| 10 | - return {}; | |
| 20 | + return { | |
| 21 | + defaultFileList: [ | |
| 22 | + { | |
| 23 | + 'name': 'Vue.js权威指南.zip', | |
| 24 | + 'url': 'http://www.baidu.com' | |
| 25 | + }, | |
| 26 | + { | |
| 27 | + 'name': 'Vue.js权威指南.doc', | |
| 28 | + 'url': 'http://www.baidu.com' | |
| 29 | + }, | |
| 30 | + { | |
| 31 | + 'name': '套马的汉子.mp3', | |
| 32 | + 'url': 'http://www.baidu.com' | |
| 33 | + }, | |
| 34 | + { | |
| 35 | + 'name': '风景.jpg', | |
| 36 | + 'url': 'http://www.baidu.com' | |
| 37 | + }, | |
| 38 | + { | |
| 39 | + 'name': 'Vue.js权威指南.mp4', | |
| 40 | + 'url': 'http://www.baidu.com' | |
| 41 | + }, | |
| 42 | + { | |
| 43 | + 'name': '套马的汉子.csv', | |
| 44 | + 'url': 'http://www.baidu.com' | |
| 45 | + }, | |
| 46 | + { | |
| 47 | + 'name': '风景.ppt', | |
| 48 | + 'url': 'http://www.baidu.com' | |
| 49 | + }, | |
| 50 | + ] | |
| 51 | + }; | |
| 11 | 52 | }, |
| 12 | 53 | computed: {}, |
| 13 | 54 | methods: {} | ... | ... |