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: {} | ... | ... |