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 | <template> | 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 | </template> | 23 | </template> |
| 4 | <script> | 24 | <script> |
| 25 | + import Icon from '../icon/icon.vue'; | ||
| 26 | + import Progress from '../progress/progress.vue'; | ||
| 27 | + const prefixCls = 'ivu-upload'; | ||
| 28 | + | ||
| 5 | export default { | 29 | export default { |
| 6 | - props: {}, | 30 | + components: { Icon, Progress }, |
| 31 | + props: { | ||
| 32 | + files: { | ||
| 33 | + type: Array, | ||
| 34 | + default() { | ||
| 35 | + return []; | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + }, | ||
| 7 | data () { | 39 | data () { |
| 8 | - return {}; | 40 | + return { |
| 41 | + prefixCls: prefixCls | ||
| 42 | + }; | ||
| 9 | }, | 43 | }, |
| 10 | computed: {}, | 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 | </script> | 93 | </script> |
| 14 | \ No newline at end of file | 94 | \ No newline at end of file |
src/components/upload/upload.vue
| 1 | <template> | 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 | </div> | 24 | </div> |
| 17 | </template> | 25 | </template> |
| 18 | <script> | 26 | <script> |
| 27 | + import UploadList from './upload-list.vue'; | ||
| 19 | import ajax from './ajax'; | 28 | import ajax from './ajax'; |
| 20 | import { oneOf } from '../../utils/assist'; | 29 | import { oneOf } from '../../utils/assist'; |
| 21 | 30 | ||
| 22 | const prefixCls = 'ivu-upload'; | 31 | const prefixCls = 'ivu-upload'; |
| 23 | 32 | ||
| 24 | export default { | 33 | export default { |
| 34 | + components: { UploadList }, | ||
| 25 | props: { | 35 | props: { |
| 26 | action: { | 36 | action: { |
| 27 | type: String, | 37 | type: String, |
| @@ -56,7 +66,8 @@ | @@ -56,7 +66,8 @@ | ||
| 56 | type: String, | 66 | type: String, |
| 57 | validator (value) { | 67 | validator (value) { |
| 58 | return oneOf(value, ['select', 'drag']); | 68 | return oneOf(value, ['select', 'drag']); |
| 59 | - } | 69 | + }, |
| 70 | + default: 'select' | ||
| 60 | }, | 71 | }, |
| 61 | format: { | 72 | format: { |
| 62 | type: Array, | 73 | type: Array, |
| @@ -133,6 +144,7 @@ | @@ -133,6 +144,7 @@ | ||
| 133 | return [ | 144 | return [ |
| 134 | `${prefixCls}`, | 145 | `${prefixCls}`, |
| 135 | { | 146 | { |
| 147 | + [`${prefixCls}-select`]: this.type === 'select', | ||
| 136 | [`${prefixCls}-drag`]: this.type === 'drag', | 148 | [`${prefixCls}-drag`]: this.type === 'drag', |
| 137 | [`${prefixCls}-dragOver`]: this.dragOver | 149 | [`${prefixCls}-dragOver`]: this.dragOver |
| 138 | } | 150 | } |
src/styles/components/upload.less
| 1 | @upload-prefix-cls: ~"@{css-prefix}upload"; | 1 | @upload-prefix-cls: ~"@{css-prefix}upload"; |
| 2 | 2 | ||
| 3 | .@{upload-prefix-cls} { | 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 | \ No newline at end of file | 76 | \ No newline at end of file |
test/routers/upload.vue
| 1 | <template> | 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 | </template> | 15 | </template> |
| 6 | <script> | 16 | <script> |
| 7 | export default { | 17 | export default { |
| 8 | props: {}, | 18 | props: {}, |
| 9 | data () { | 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 | computed: {}, | 53 | computed: {}, |
| 13 | methods: {} | 54 | methods: {} |