From 5793481ba4b2fe286486b2767bc93079ad3cb647 Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 5 Jul 2020 20:09:20 +0800 Subject: [PATCH] feat(Uploader): add preview-cover slot (#6707) * feat(Uploader): add preview-cover slot * docs: upd * fix: case name --- src/uploader/README.md | 60 +++++++++---- src/uploader/README.zh-CN.md | 90 ++++++++++++------- src/uploader/demo/index.vue | 66 ++++++++++---- src/uploader/index.js | 10 ++- src/uploader/index.less | 8 ++ .../test/__snapshots__/demo.spec.js.snap | 43 +++++++-- .../test/__snapshots__/index.spec.js.snap | 25 ++++++ src/uploader/test/index.spec.js | 13 +++ 8 files changed, 240 insertions(+), 75 deletions(-) diff --git a/src/uploader/README.md b/src/uploader/README.md index 7ad8e128b..62271d6d2 100644 --- a/src/uploader/README.md +++ b/src/uploader/README.md @@ -43,12 +43,6 @@ export default { }; ``` -### Disabled - -```html - -``` - ### Upload Status ```html @@ -106,32 +100,54 @@ export default { ### Max Size ```html - + ``` ```js +import { Toast } from 'vant'; + export default { methods: { onOversize(file) { console.log(file); + Toast('File size cannot exceed 500kb); }, }, }; ``` -### Upload Style +### Custom Upload Area ```html - Upload Image + Upload Image ``` +### Preview Cover + +```html + + + + + +``` + ### Before Read ```html @@ -167,12 +183,21 @@ export default { }; ``` +### Disable Uploader + +Use `disabled` prop to disable uploader. + +```html + +``` + ## API ### Props | Attribute | Description | Type | Default | | --- | --- | --- | --- | +| v-model (fileList) | List of uploaded files | _FileListItem[]_ | - | | accept | Accepted [file type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers) | _string_ | `image/*` | | name `v2.0.3` | Input name | _number \| string_ | - | | preview-size | Size of preview image | _number \| string_ | `80px` | @@ -205,9 +230,10 @@ export default { ### Slots -| Name | Description | -| ------- | ----------- | -| default | Custom icon | +| Name | Description | SlotProps | +| --- | --- | --- | +| default | Custom icon | - | +| preview-cover `v2.9.1` | Custom content that covers the image preview | `item: FileListItem` | ### Parematers of before-read、after-read、before-delete diff --git a/src/uploader/README.zh-CN.md b/src/uploader/README.zh-CN.md index ac3d964c4..fa14d0286 100644 --- a/src/uploader/README.zh-CN.md +++ b/src/uploader/README.zh-CN.md @@ -13,7 +13,7 @@ Vue.use(Uploader); ### 基础用法 -文件上传完毕后会触发`after-read`回调函数,获取到对应的`file`对象 +文件上传完毕后会触发 `after-read` 回调函数,获取到对应的 `file` 对象。 ```html @@ -32,7 +32,7 @@ export default { ### 文件预览 -通过`v-model`可以绑定已经上传的文件列表,并展示文件列表的预览图 +通过`v-model`可以绑定已经上传的文件列表,并展示文件列表的预览图。 ```html @@ -53,17 +53,9 @@ export default { }; ``` -### 禁用 - -通过`disabled`属性禁用文件上传 - -```html - -``` - ### 上传状态 -通过`status`属性可以标识上传状态,`uploading`表示上传中,`failed`表示上传失败,`done`表示上传完成(从 2.4.7 版本开始支持) +通过 `status` 属性可以标识上传状态,`uploading` 表示上传中,`failed` 表示上传失败,`done` 表示上传完成。 ```html @@ -103,7 +95,7 @@ export default { ### 限制上传数量 -通过`max-count`属性可以限制上传文件的数量,上传数量达到限制后,会自动隐藏上传区域 +通过 `max-count` 属性可以限制上传文件的数量,上传数量达到限制后,会自动隐藏上传区域。 ```html @@ -121,22 +113,20 @@ export default { ### 限制上传大小 -通过`max-size`属性可以限制上传文件的大小,超过大小的文件会被自动过滤,这些文件信息可以通过`oversize`事件获取 +通过 `max-size` 属性可以限制上传文件的大小,超过大小的文件会被自动过滤,这些文件信息可以通过 `oversize` 事件获取。 ```html - + ``` ```js +import Toast from 'vant'; + export default { methods: { onOversize(file) { console.log(file); + Toast('文件大小不能超过 500kb'); }, }, }; @@ -144,17 +134,43 @@ export default { ### 自定义上传样式 -通过插槽可以自定义上传区域的样式 +通过默认插槽可以自定义上传区域的样式。 ```html - 上传文件 + 上传文件 ``` -### 上传前自定义处理 +### 自定义预览样式 -通过传入`beforeRead`函数可以在上传前进行校验,返回`true`表示校验通过,返回`false`表示校验失败。支持返回`Promise`对 file 对象进行自定义处理,例如压缩图片。 +通过 `preview-cover` 插槽可以自定义覆盖在预览区域上方的内容。 + +```html + + + + + +``` + +### 上传前置处理 + +通过传入 `beforeRead` 函数可以在上传前进行校验和处理,返回 `true` 表示校验通过,返回 `false` 表示校验失败。支持返回 `Promise` 对 file 对象进行自定义处理,例如压缩图片。 ```html @@ -191,12 +207,21 @@ export default { }; ``` +### 禁用文件上传 + +通过 `disabled` 属性禁用文件上传 + +```html + +``` + ## API ### Props | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | +| v-model (fileList) | 已上传的文件列表 | _FileListItem[]_ | - | | accept | 允许上传的文件类型,[详细说明](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/file#%E9%99%90%E5%88%B6%E5%85%81%E8%AE%B8%E7%9A%84%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B) | _string_ | `image/*` | | name `v2.0.3` | 标识符,可以在回调函数的第二项参数中获取 | _number \| string_ | - | | preview-size | 预览图和上传区域的尺寸,默认单位为`px` | _number \| string_ | `80px` | @@ -207,13 +232,13 @@ export default { | deletable `v2.2.12` | 是否展示删除按钮 | _boolean_ | `true` | | show-upload `v2.5.6` | 是否展示上传区域 | _boolean_ | `true` | | lazy-load `v2.6.2` | 是否开启图片懒加载,须配合 [Lazyload](#/zh-CN/lazyload) 组件使用 | _boolean_ | `false` | -| capture | 图片选取模式,可选值为`camera`(直接调起摄像头) | _string_ | - | +| capture | 图片选取模式,可选值为 `camera` (直接调起摄像头) | _string_ | - | | after-read | 文件读取完成后的回调函数 | _Function_ | - | -| before-read | 文件读取前的回调函数,返回`false`可终止文件读取,
支持返回`Promise` | _Function_ | - | -| before-delete | 文件删除前的回调函数,返回`false`可终止文件读取,
支持返回`Promise` | _Function_ | - | -| max-size | 文件大小限制,单位为`byte` | _number \| string_ | - | +| before-read | 文件读取前的回调函数,返回 `false` 可终止文件读取,
支持返回`Promise` | _Function_ | - | +| before-delete | 文件删除前的回调函数,返回 `false` 可终止文件读取,
支持返回`Promise` | _Function_ | - | +| max-size | 文件大小限制,单位为 `byte` | _number \| string_ | - | | max-count | 文件上传数量限制 | _number \| string_ | - | -| result-type `v2.2.7` | 文件读取结果类型,可选值为`file` `text` | _string_ | `dataUrl` | +| result-type `v2.2.7` | 文件读取结果类型,可选值为 `file` `text` | _string_ | `dataUrl` | | upload-text | 上传区域文字提示 | _string_ | - | | image-fit `v2.1.5` | 预览图裁剪模式,可选值见 [Image](#/zh-CN/image) 组件 | _string_ | `cover` | | upload-icon `v2.5.4` | 上传区域[图标名称](#/zh-CN/icon)或图片链接 | _string_ | `photograph` | @@ -229,9 +254,10 @@ export default { ### Slots -| 名称 | 说明 | -| ------- | -------------- | -| default | 自定义上传区域 | +| 名称 | 说明 | SlotProps | +| --- | --- | --- | +| default | 自定义上传区域 | - | +| preview-cover `v2.9.1` | 自定义覆盖在预览区域上方的内容 | `item: FileListItem` | ### 回调参数 @@ -239,7 +265,7 @@ before-read、after-read、before-delete 执行时会传递以下回调参数: | 参数名 | 说明 | 类型 | | ------ | --------------------------------- | -------- | -| file | 文件解析后的 file 对象 | _object_ | +| file | file 对象 | _object_ | | detail | 额外信息,包含 name 和 index 字段 | _object_ | ### ResultType  可选值 diff --git a/src/uploader/demo/index.vue b/src/uploader/demo/index.vue index 4e879a3ef..e28cbe625 100644 --- a/src/uploader/demo/index.vue +++ b/src/uploader/demo/index.vue @@ -8,10 +8,6 @@ - - - - @@ -24,23 +20,34 @@ - + - + {{ t('upload') }} + + + + + + + + + + @@ -52,26 +59,32 @@ export default { failed: '上传失败', upload: '上传文件', preview: '文件预览', - disabled: '禁用', + maxSize: '限制上传大小', + disabled: '禁用文件上传', maxCount: '限制上传数量', uploading: '上传中...', - beforeRead: '上传前校验', - uploadStyle: '自定义上传样式', + imageName: '图片名称', + beforeRead: '上传前置处理', + overSizeTip: '文件大小不能超过 500kb', invalidType: '请上传 jpg 格式图片', - maxSize: '限制上传大小(3M)', + customUpload: '自定义上传样式', + previewCover: '自定义预览样式', }, 'en-US': { status: 'Upload Status', failed: 'Failed', upload: 'Upload File', preview: 'Preview File', - disabled: 'Disabled', + maxSize: 'Max Size', + disabled: 'Disable Uploader', maxCount: 'Max Count', uploading: 'Uploading...', + imageName: 'Image Name', beforeRead: 'Before Read', - uploadStyle: 'Upload Style', + overSizeTip: 'File size cannot exceed 500kb', invalidType: 'Please upload an image in jpg format', - maxSize: 'Max Size(3M)', + customUpload: 'Custom Upload Area', + previewCover: 'Preview Cover', }, }, @@ -83,8 +96,9 @@ export default { ], fileList2: [{ url: 'https://img.yzcdn.cn/vant/sand.jpg' }], fileList3: [], - fileList4: [], + fileList4: [{ url: 'https://img.yzcdn.cn/vant/sand.jpg' }], statusFileList: [], + previewCoverFiles: [], }; }, @@ -101,6 +115,13 @@ export default { message: this.t('failed'), } ); + + this.previewCoverFiles.push({ + url: 'https://img.yzcdn.cn/vant/leaf.jpg', + file: { + name: this.t('imageName'), + }, + }); }, methods: { @@ -129,6 +150,7 @@ export default { onOversize(file, detail) { console.log(file, detail); + this.$toast(this.t('overSizeTip')); }, }, }; @@ -143,5 +165,17 @@ export default { .van-uploader { margin-left: @padding-md; } + + .preview-cover { + position: absolute; + bottom: 0; + box-sizing: border-box; + width: 100%; + padding: 4px; + color: #fff; + font-size: 12px; + text-align: center; + background: rgba(0, 0, 0, 0.3); + } } diff --git a/src/uploader/index.js b/src/uploader/index.js index 11d33ea58..4f38acb43 100644 --- a/src/uploader/index.js +++ b/src/uploader/index.js @@ -318,6 +318,11 @@ export default createComponent({ /> ); + const PreviewCoverContent = this.slots('preview-cover', item); + const PreviewCover = PreviewCoverContent && ( +
{PreviewCoverContent}
+ ); + const Preview = isImageFile(item) ? ( { this.onPreviewImage(item); }} - /> + > + {PreviewCover} + ) : (
{item.file ? item.file.name : item.url}
+ {PreviewCover} ); diff --git a/src/uploader/index.less b/src/uploader/index.less index 379f2d849..230486207 100644 --- a/src/uploader/index.less +++ b/src/uploader/index.less @@ -83,6 +83,14 @@ background-color: @uploader-delete-background-color; border-radius: 100%; } + + &-cover { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } } &__mask { diff --git a/src/uploader/test/__snapshots__/demo.spec.js.snap b/src/uploader/test/__snapshots__/demo.spec.js.snap index 53bed7a35..b9933f7e4 100644 --- a/src/uploader/test/__snapshots__/demo.spec.js.snap +++ b/src/uploader/test/__snapshots__/demo.spec.js.snap @@ -32,14 +32,6 @@ exports[`renders demo correctly 1`] = ` -
-
-
-
-
-
-
-
@@ -87,6 +79,13 @@ exports[`renders demo correctly 1`] = `
+
+
+
+
+
+ +
@@ -96,7 +95,7 @@ exports[`renders demo correctly 1`] = `
+
+
+
+
+
+
+
+
+
图片名称
+
+
+ +
+
+
+
+
+
@@ -112,5 +129,13 @@ exports[`renders demo correctly 1`] = `
+
+
+
+
+
+
+
+
`; diff --git a/src/uploader/test/__snapshots__/index.spec.js.snap b/src/uploader/test/__snapshots__/index.spec.js.snap index 2e8bf4f7c..60e2160f8 100644 --- a/src/uploader/test/__snapshots__/index.spec.js.snap +++ b/src/uploader/test/__snapshots__/index.spec.js.snap @@ -67,6 +67,31 @@ exports[`max-count prop 1`] = `
`; +exports[`preview-cover slot 1`] = ` +
+
+
+
+
+
+
https://img.yzcdn.cn/vant/cat.jpeg
+
+ +
+
+
+
+
+
https://img.yzcdn.cn/vant/cat.jpeg
+
+ +
+
+
+
+
+`; + exports[`preview-size prop 1`] = `
diff --git a/src/uploader/test/index.spec.js b/src/uploader/test/index.spec.js index cbddaaf05..5aa5c894d 100644 --- a/src/uploader/test/index.spec.js +++ b/src/uploader/test/index.spec.js @@ -507,3 +507,16 @@ test('multiFile upload filter max-size file', async () => { expect(wrapper.emitted('oversize')[0]).toBeTruthy(); }); + +test('preview-cover slot', () => { + const wrapper = mount(Uploader, { + propsData: { + fileList: [{ url: IMAGE }, { url: IMAGE }], + }, + scopedSlots: { + 'preview-cover': (item) => item.url, + }, + }); + + expect(wrapper).toMatchSnapshot(); +});