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