From 729b9dac4b128b4a69ff4df1e859fef76e578d3b Mon Sep 17 00:00:00 2001 From: neverland Date: Thu, 20 Jun 2019 16:14:07 +0800 Subject: [PATCH] [new feature] Uploader: before-read support promise mode (#3572) --- packages/uploader/demo/index.vue | 27 +++++++++++-- packages/uploader/en-US.md | 34 ++++++++++++++++- packages/uploader/index.js | 24 ++++++++++-- .../test/__snapshots__/demo.spec.js.snap | 8 ++++ packages/uploader/test/index.spec.js | 36 ++++++++++++++++++ packages/uploader/zh-CN.md | 38 ++++++++++++++++++- 6 files changed, 159 insertions(+), 8 deletions(-) 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 |