提交 | 用户 | age
|
d98d05
|
1 |
import { VantComponent } from '../common/component'; |
53cc6f
|
2 |
import { isImageFile, chooseFile, isVideoFile } from './utils'; |
d98d05
|
3 |
import { chooseImageProps, chooseVideoProps } from './shared'; |
53cc6f
|
4 |
import { isBoolean, isPromise } from '../common/validator'; |
d98d05
|
5 |
VantComponent({ |
S |
6 |
props: Object.assign( |
|
7 |
Object.assign( |
|
8 |
{ |
|
9 |
disabled: Boolean, |
|
10 |
multiple: Boolean, |
|
11 |
uploadText: String, |
|
12 |
useBeforeRead: Boolean, |
|
13 |
afterRead: null, |
|
14 |
beforeRead: null, |
|
15 |
previewSize: { |
|
16 |
type: null, |
53cc6f
|
17 |
value: 80, |
d98d05
|
18 |
}, |
S |
19 |
name: { |
53cc6f
|
20 |
type: null, |
d98d05
|
21 |
value: '', |
S |
22 |
}, |
|
23 |
accept: { |
|
24 |
type: String, |
|
25 |
value: 'image', |
|
26 |
}, |
|
27 |
fileList: { |
|
28 |
type: Array, |
|
29 |
value: [], |
|
30 |
observer: 'formatFileList', |
|
31 |
}, |
|
32 |
maxSize: { |
|
33 |
type: Number, |
|
34 |
value: Number.MAX_VALUE, |
|
35 |
}, |
|
36 |
maxCount: { |
|
37 |
type: Number, |
|
38 |
value: 100, |
|
39 |
}, |
|
40 |
deletable: { |
|
41 |
type: Boolean, |
|
42 |
value: true, |
|
43 |
}, |
|
44 |
showUpload: { |
|
45 |
type: Boolean, |
|
46 |
value: true, |
|
47 |
}, |
|
48 |
previewImage: { |
|
49 |
type: Boolean, |
|
50 |
value: true, |
|
51 |
}, |
|
52 |
previewFullImage: { |
|
53 |
type: Boolean, |
|
54 |
value: true, |
|
55 |
}, |
|
56 |
imageFit: { |
|
57 |
type: String, |
|
58 |
value: 'scaleToFill', |
|
59 |
}, |
|
60 |
uploadIcon: { |
|
61 |
type: String, |
|
62 |
value: 'photograph', |
|
63 |
}, |
|
64 |
}, |
|
65 |
chooseImageProps |
|
66 |
), |
|
67 |
chooseVideoProps |
|
68 |
), |
|
69 |
data: { |
|
70 |
lists: [], |
|
71 |
isInCount: true, |
|
72 |
}, |
|
73 |
methods: { |
|
74 |
formatFileList() { |
|
75 |
const { fileList = [], maxCount } = this.data; |
|
76 |
const lists = fileList.map((item) => |
|
77 |
Object.assign(Object.assign({}, item), { |
53cc6f
|
78 |
isImage: isImageFile(item), |
S |
79 |
isVideo: isVideoFile(item), |
|
80 |
deletable: isBoolean(item.deletable) ? item.deletable : true, |
d98d05
|
81 |
}) |
S |
82 |
); |
|
83 |
this.setData({ lists, isInCount: lists.length < maxCount }); |
|
84 |
}, |
|
85 |
getDetail(index) { |
|
86 |
return { |
|
87 |
name: this.data.name, |
|
88 |
index: index == null ? this.data.fileList.length : index, |
|
89 |
}; |
|
90 |
}, |
|
91 |
startUpload() { |
53cc6f
|
92 |
const { maxCount, multiple, lists, disabled } = this.data; |
d98d05
|
93 |
if (disabled) return; |
S |
94 |
chooseFile( |
|
95 |
Object.assign(Object.assign({}, this.data), { |
|
96 |
maxCount: maxCount - lists.length, |
|
97 |
}) |
|
98 |
) |
|
99 |
.then((res) => { |
53cc6f
|
100 |
this.onBeforeRead(multiple ? res : res[0]); |
d98d05
|
101 |
}) |
S |
102 |
.catch((error) => { |
|
103 |
this.$emit('error', error); |
|
104 |
}); |
|
105 |
}, |
|
106 |
onBeforeRead(file) { |
|
107 |
const { beforeRead, useBeforeRead } = this.data; |
|
108 |
let res = true; |
|
109 |
if (typeof beforeRead === 'function') { |
|
110 |
res = beforeRead(file, this.getDetail()); |
|
111 |
} |
|
112 |
if (useBeforeRead) { |
|
113 |
res = new Promise((resolve, reject) => { |
|
114 |
this.$emit( |
|
115 |
'before-read', |
|
116 |
Object.assign(Object.assign({ file }, this.getDetail()), { |
|
117 |
callback: (ok) => { |
|
118 |
ok ? resolve() : reject(); |
|
119 |
}, |
|
120 |
}) |
|
121 |
); |
|
122 |
}); |
|
123 |
} |
|
124 |
if (!res) { |
|
125 |
return; |
|
126 |
} |
|
127 |
if (isPromise(res)) { |
|
128 |
res.then((data) => this.onAfterRead(data || file)); |
|
129 |
} else { |
|
130 |
this.onAfterRead(file); |
|
131 |
} |
|
132 |
}, |
|
133 |
onAfterRead(file) { |
53cc6f
|
134 |
const { maxSize, afterRead } = this.data; |
d98d05
|
135 |
const oversize = Array.isArray(file) |
S |
136 |
? file.some((item) => item.size > maxSize) |
|
137 |
: file.size > maxSize; |
|
138 |
if (oversize) { |
|
139 |
this.$emit('oversize', Object.assign({ file }, this.getDetail())); |
|
140 |
return; |
|
141 |
} |
53cc6f
|
142 |
if (typeof afterRead === 'function') { |
S |
143 |
afterRead(file, this.getDetail()); |
d98d05
|
144 |
} |
S |
145 |
this.$emit('after-read', Object.assign({ file }, this.getDetail())); |
|
146 |
}, |
|
147 |
deleteItem(event) { |
|
148 |
const { index } = event.currentTarget.dataset; |
|
149 |
this.$emit( |
|
150 |
'delete', |
|
151 |
Object.assign(Object.assign({}, this.getDetail(index)), { |
|
152 |
file: this.data.fileList[index], |
|
153 |
}) |
|
154 |
); |
|
155 |
}, |
|
156 |
onPreviewImage(event) { |
|
157 |
if (!this.data.previewFullImage) return; |
|
158 |
const { index } = event.currentTarget.dataset; |
|
159 |
const { lists } = this.data; |
|
160 |
const item = lists[index]; |
|
161 |
wx.previewImage({ |
53cc6f
|
162 |
urls: lists.filter((item) => isImageFile(item)).map((item) => item.url), |
S |
163 |
current: item.url, |
d98d05
|
164 |
fail() { |
S |
165 |
wx.showToast({ title: '预览图片失败', icon: 'none' }); |
|
166 |
}, |
|
167 |
}); |
|
168 |
}, |
53cc6f
|
169 |
onPreviewVideo(event) { |
S |
170 |
if (!this.data.previewFullImage) return; |
|
171 |
const { index } = event.currentTarget.dataset; |
|
172 |
const { lists } = this.data; |
|
173 |
wx.previewMedia({ |
|
174 |
sources: lists |
|
175 |
.filter((item) => isVideoFile(item)) |
|
176 |
.map((item) => |
|
177 |
Object.assign(Object.assign({}, item), { type: 'video' }) |
|
178 |
), |
|
179 |
current: index, |
|
180 |
fail() { |
|
181 |
wx.showToast({ title: '预览视频失败', icon: 'none' }); |
|
182 |
}, |
|
183 |
}); |
|
184 |
}, |
|
185 |
onPreviewFile(event) { |
|
186 |
const { index } = event.currentTarget.dataset; |
|
187 |
wx.openDocument({ |
|
188 |
filePath: this.data.lists[index].url, |
|
189 |
showMenu: true, |
|
190 |
}); |
|
191 |
}, |
d98d05
|
192 |
onClickPreview(event) { |
S |
193 |
const { index } = event.currentTarget.dataset; |
|
194 |
const item = this.data.lists[index]; |
|
195 |
this.$emit( |
|
196 |
'click-preview', |
|
197 |
Object.assign(Object.assign({}, item), this.getDetail(index)) |
|
198 |
); |
|
199 |
}, |
|
200 |
}, |
|
201 |
}); |