diff --git a/packages/uploader/demo/index.vue b/packages/uploader/demo/index.vue
index 234b90912..3d89fd9e2 100644
--- a/packages/uploader/demo/index.vue
+++ b/packages/uploader/demo/index.vue
@@ -29,6 +29,13 @@
+
+
+
+
@@ -39,24 +46,38 @@ export default {
upload: '上传图片',
preview: '图片预览',
maxCount: '限制上传数量',
- uploadStyle: '自定义上传样式'
+ beforeRead: '上传前校验',
+ uploadStyle: '自定义上传样式',
+ invalidType: '请上传 jpg 格式图片'
},
'en-US': {
upload: 'Upload Image',
preview: 'Preview Image',
maxCount: 'Max Count',
- uploadStyle: 'Upload Style'
+ beforeRead: 'Before Read',
+ uploadStyle: 'Upload Style',
+ invalidType: 'Please upload an image in jpg format'
}
},
data() {
return {
fileList: [],
- fileList2: []
+ fileList2: [],
+ fileList3: []
};
},
methods: {
+ beforeRead(file) {
+ if (file.type !== 'image/jpeg') {
+ this.$toast(this.$t('invalidType'));
+ return false;
+ }
+
+ return true;
+ },
+
afterRead(file) {
console.log(file);
}
diff --git a/packages/uploader/en-US.md b/packages/uploader/en-US.md
index 4582b50ff..98188651b 100644
--- a/packages/uploader/en-US.md
+++ b/packages/uploader/en-US.md
@@ -70,6 +70,38 @@ export default {
```
+### Before Read
+
+```html
+
+```
+
+```js
+export default {
+ methods: {
+ beforeRead(file) {
+ if (file.type !== 'image/jpeg') {
+ Toast('Please upload an image in jpg format');
+ return false;
+ }
+
+ return true;
+ },
+
+ asyncBeforeRead(file) {
+ return new Promise((resolve, reject) => {
+ if (file.type !== 'image/jpeg') {
+ Toast('Please upload an image in jpg format');
+ reject();
+ } else {
+ resolve();
+ }
+ });
+ }
+ }
+}
+```
+
## API
### Props
@@ -83,7 +115,7 @@ export default {
| multiple | Whether to enable multiple selection pictures | `Boolean` | `false` |
| disabled | Whether to disabled the upload | `Boolean` | `false` |
| capture | Capture,can be set to `camera` | `String` | - |
-| before-read | Hook before reading the file, return false to stop reading the file | `Function` | - |
+| before-read | Hook before reading the file, return false to stop reading the file, can return Promise | `Function` | - |
| after-read | Hook after reading the file | `Function` | - |
| max-size | Max size of file | `Number` | - |
| max-count | Max count of image | `Number` | - |
diff --git a/packages/uploader/index.js b/packages/uploader/index.js
index 534ab8a48..d1dcf0a41 100644
--- a/packages/uploader/index.js
+++ b/packages/uploader/index.js
@@ -59,11 +59,29 @@ export default sfc({
files = files.length === 1 ? files[0] : [].slice.call(files);
- if (this.beforeRead && !this.beforeRead(files, this.detail)) {
- this.resetInput();
- return;
+ if (this.beforeRead) {
+ const response = this.beforeRead(files, this.detail);
+
+ if (!response) {
+ this.resetInput();
+ return;
+ }
+
+ if (response.then) {
+ response
+ .then(() => {
+ this.readFile(files);
+ })
+ .catch(this.resetInput);
+
+ return;
+ }
}
+ this.readFile(files);
+ },
+
+ readFile(files) {
const oversize = isOversize(files, this.maxSize);
if (Array.isArray(files)) {
diff --git a/packages/uploader/test/__snapshots__/demo.spec.js.snap b/packages/uploader/test/__snapshots__/demo.spec.js.snap
index 4e06c336a..dfc0d351a 100644
--- a/packages/uploader/test/__snapshots__/demo.spec.js.snap
+++ b/packages/uploader/test/__snapshots__/demo.spec.js.snap
@@ -36,5 +36,13 @@ exports[`renders demo correctly 1`] = `
+
`;
diff --git a/packages/uploader/test/index.spec.js b/packages/uploader/test/index.spec.js
index 7f03830ce..0ed443c30 100644
--- a/packages/uploader/test/index.spec.js
+++ b/packages/uploader/test/index.spec.js
@@ -94,6 +94,42 @@ it('before read return false', () => {
expect(input.element.value).toEqual('');
});
+it('before read return promise and resolve', async () => {
+ const afterRead = jest.fn();
+ const wrapper = mount(Uploader, {
+ propsData: {
+ beforeRead: () => new Promise(resolve => {
+ resolve();
+ }),
+ afterRead
+ }
+ });
+
+ wrapper.vm.onChange(file);
+
+ await later();
+ expect(afterRead).toHaveBeenCalledTimes(1);
+});
+
+it('before read return promise and reject', async () => {
+ const afterRead = jest.fn();
+ const wrapper = mount(Uploader, {
+ propsData: {
+ beforeRead: () => new Promise((resolve, reject) => {
+ reject();
+ }),
+ afterRead
+ }
+ });
+
+ const input = wrapper.find('input');
+
+ await later();
+ wrapper.vm.onChange(file);
+ expect(afterRead).toHaveBeenCalledTimes(0);
+ expect(input.element.value).toEqual('');
+});
+
test('file size overlimit', async () => {
const wrapper = mount(Uploader, {
propsData: {
diff --git a/packages/uploader/zh-CN.md b/packages/uploader/zh-CN.md
index 80b04fd47..07f851fd4 100644
--- a/packages/uploader/zh-CN.md
+++ b/packages/uploader/zh-CN.md
@@ -79,6 +79,42 @@ export default {
```
+### 上传前校验
+
+通过传入`beforeRead`函数可以在上传前进行校验,返回`true`表示校验通过,返回`false`表示校验失败。支持返回`Promise`进行异步校验
+
+```html
+
+```
+
+```js
+export default {
+ methods: {
+ // 返回布尔值
+ beforeRead(file) {
+ if (file.type !== 'image/jpeg') {
+ Toast('请上传 jpg 格式图片');
+ return false;
+ }
+
+ return true;
+ },
+
+ // 返回 Promise
+ asyncBeforeRead(file) {
+ return new Promise((resolve, reject) => {
+ if (file.type !== 'image/jpeg') {
+ Toast('请上传 jpg 格式图片');
+ reject();
+ } else {
+ resolve();
+ }
+ });
+ }
+ }
+}
+```
+
## API
### Props
@@ -92,7 +128,7 @@ export default {
| multiple | 是否开启图片多选,部分安卓机型不支持 | `Boolean` | `false` | 2.0.0 |
| disabled | 是否禁用图片上传 | `Boolean` | `false` | - |
| capture | 图片选取模式,可选值为`camera`(直接调起摄像头) | `String` | - | 2.0.0 |
-| before-read | 文件读取前的回调函数,返回`false`可终止文件读取 | `Function` | - | - |
+| before-read | 文件读取前的回调函数,返回`false`可终止文件读取,支持返回`Promise` | `Function` | - | - |
| after-read | 文件读取完成后的回调函数 | `Function` | - | - |
| max-size | 文件大小限制,单位为`byte` | `Number` | - | - |
| max-count | 图片上传数量限制 | `Number` | - | 2.0.0 |