diff --git a/docs/markdown/changelog.zh-CN.md b/docs/markdown/changelog.zh-CN.md index f08f646dc..10f2cb7a8 100644 --- a/docs/markdown/changelog.zh-CN.md +++ b/docs/markdown/changelog.zh-CN.md @@ -22,6 +22,7 @@ ##### Uploader - 新增`preview`属性 +- 新增`max-count`属性 ### [v2.0.0-beta.3](https://github.com/youzan/vant/tree/v2.0.0-beta.3) diff --git a/packages/uploader/demo/index.vue b/packages/uploader/demo/index.vue index 4fc826b52..e72864a4e 100644 --- a/packages/uploader/demo/index.vue +++ b/packages/uploader/demo/index.vue @@ -4,6 +4,14 @@ + + + + +``` + ### Upload Style ```html @@ -49,6 +59,7 @@ export default { | before-read | Hook before reading the file, return false to stop reading the file | `Function` | - | | after-read | Hook after reading the file | `Function` | - | | max-size | Max size of file | `Number` | - | +| max-count | Max count of image | `Number` | - | | result-type | Type of file read result, can be set to `dataUrl` `text` | `String` | `dataUrl` | | upload-text | Upload text | `String` | - | diff --git a/packages/uploader/index.js b/packages/uploader/index.js index 3432c2936..b757c9589 100644 --- a/packages/uploader/index.js +++ b/packages/uploader/index.js @@ -24,6 +24,10 @@ export default sfc({ maxSize: { type: Number, default: Number.MAX_VALUE + }, + maxCount: { + type: Number, + default: Number.MAX_VALUE } }, @@ -44,17 +48,22 @@ export default sfc({ methods: { onChange(event) { let { files } = event.target; + if (this.disabled || !files.length) { return; } files = files.length === 1 ? files[0] : [].slice.call(files, 0); + if (!files || (this.beforeRead && !this.beforeRead(files, this.detail))) { this.resetInput(); return; } if (Array.isArray(files)) { + const maxCount = this.maxCount - this.previewImages.length; + files = files.slice(0, maxCount); + Promise.all(files.map(this.readFile)).then(contents => { let oversize = false; const payload = files.map((file, index) => { @@ -96,17 +105,19 @@ export default sfc({ onAfterRead(files, oversize) { if (oversize) { this.$emit('oversize', files, this.detail); - } else { - if (Array.isArray(files)) { - files.forEach(this.addPreviewImage); - } else { - this.addPreviewImage(files); - } - - if (this.afterRead) { - this.afterRead(files, this.detail); - } + return; } + + if (Array.isArray(files)) { + files.forEach(this.addPreviewImage); + } else { + this.addPreviewImage(files); + } + + if (this.afterRead) { + this.afterRead(files, this.detail); + } + this.resetInput(); }, @@ -130,6 +141,10 @@ export default sfc({ }, renderUpload() { + if (this.previewImages.length >= this.maxCount) { + return; + } + const slot = this.slots(); const Input = ( diff --git a/packages/uploader/test/__snapshots__/demo.spec.js.snap b/packages/uploader/test/__snapshots__/demo.spec.js.snap index 563555e0d..60b1b1a24 100644 --- a/packages/uploader/test/__snapshots__/demo.spec.js.snap +++ b/packages/uploader/test/__snapshots__/demo.spec.js.snap @@ -10,6 +10,14 @@ exports[`renders demo correctly 1`] = ` +
+
+
+
+
+
+
+
diff --git a/packages/uploader/test/__snapshots__/index.spec.js.snap b/packages/uploader/test/__snapshots__/index.spec.js.snap index 9f2f79feb..83619fcf5 100644 --- a/packages/uploader/test/__snapshots__/index.spec.js.snap +++ b/packages/uploader/test/__snapshots__/index.spec.js.snap @@ -1,5 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`max-count prop 1`] = ` +
+
+
+
+
+
+
+
+`; + exports[`render preview image 1`] = `
diff --git a/packages/uploader/test/index.spec.js b/packages/uploader/test/index.spec.js index 45cbeae40..1e522be66 100644 --- a/packages/uploader/test/index.spec.js +++ b/packages/uploader/test/index.spec.js @@ -136,3 +136,17 @@ it('render preview image', async () => { expect(wrapper).toMatchSnapshot(); }); + +it('max-count prop', async () => { + const wrapper = mount(Uploader, { + propsData: { + preview: true, + maxCount: 1 + } + }); + + wrapper.vm.onChange(multiFile); + await later(); + + expect(wrapper).toMatchSnapshot(); +}); diff --git a/packages/uploader/zh-CN.md b/packages/uploader/zh-CN.md index 54b7b051d..faf916c99 100644 --- a/packages/uploader/zh-CN.md +++ b/packages/uploader/zh-CN.md @@ -12,6 +12,8 @@ Vue.use(Uploader); ### 基础用法 +图片上传完毕后会触发`after-read`传入的回调函数,获取到对应的`file`对象 + ```html ``` @@ -26,8 +28,22 @@ export default { }; ``` +### 上传数量限制 + +通过`max-count`属性可以限制上传图片的数量。上传数量达到限制后,会自动隐藏上传区域 + +```html + +``` + ### 自定义上传样式 +通过插槽可以自定义上传区域的样式 + ```html 上传图片 @@ -49,6 +65,7 @@ export default { | before-read | 文件读取前的回调函数,返回`false`可终止文件读取 | `Function` | - | - | | after-read | 文件读取完成后的回调函数 | `Function` | - | - | | max-size | 文件大小限制,单位为`byte` | `Number` | - | - | +| max-count | 图片上传数量限制 | `Number` | - | 2.0.0 | | result-type | 文件读取结果类型,可选值为`text` | `String` | `dataUrl` | - | | upload-text | 上传区域文字提示 | `String` | - | 2.0.0 | @@ -56,7 +73,7 @@ export default { | 事件名 | 说明 | 回调参数 | |------|------|------| -| oversize | 文件大小超过限制时触发 | 同 after-read | +| oversize | 文件大小超过限制时触发 | 同`after-read` | ### Slots