mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-26 08:19:15 +08:00
feat(Uploader): max-size prop can be a function (#8744)
* feat(Uploader): max-size prop can be a function * chore: revert demo * test: fix snapshot * docs: upd
This commit is contained in:
parent
5b6dadc39f
commit
833064adbd
@ -146,6 +146,28 @@ export default {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you need to make different size limits for different types of files, you can pass a function to the `max-size` props.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-uploader multiple :max-size="isOverSize" />
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Toast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const isOverSize = (file) => {
|
||||||
|
const maxSize = file.type === 'image/jpeg' ? 500 * 1024 : 1000 * 1024;
|
||||||
|
return file.size >= maxSize;
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
isOverSize,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### Custom Upload Area
|
### Custom Upload Area
|
||||||
|
|
||||||
```html
|
```html
|
||||||
@ -274,7 +296,7 @@ export default {
|
|||||||
| name | Input name | _number \| string_ | - |
|
| name | Input name | _number \| string_ | - |
|
||||||
| preview-size | Size of preview image | _number \| string_ | `80px` |
|
| preview-size | Size of preview image | _number \| string_ | `80px` |
|
||||||
| preview-image | Whether to show image preview | _boolean_ | `true` |
|
| preview-image | Whether to show image preview | _boolean_ | `true` |
|
||||||
| preview-full-image | Whethe to show full screen image preview when image is clicked | _boolean_ | `true` |
|
| preview-full-image | Whether to show full screen image preview when image is clicked | _boolean_ | `true` |
|
||||||
| preview-options | Options of full screen image preview,see [ImagePreview](#/en-US/image-preview) | _object_ | - |
|
| preview-options | Options of full screen image preview,see [ImagePreview](#/en-US/image-preview) | _object_ | - |
|
||||||
| multiple | Whether to enable multiple selection pictures | _boolean_ | `false` |
|
| multiple | Whether to enable multiple selection pictures | _boolean_ | `false` |
|
||||||
| disabled | Whether to disabled the upload | _boolean_ | `false` |
|
| disabled | Whether to disabled the upload | _boolean_ | `false` |
|
||||||
@ -285,7 +307,7 @@ export default {
|
|||||||
| after-read | Hook after reading the file | _Function_ | - |
|
| after-read | Hook after reading the file | _Function_ | - |
|
||||||
| before-read | Hook before reading the file, return false to stop reading the file, can return Promise | _Function_ | - |
|
| before-read | Hook before reading the file, return false to stop reading the file, can return Promise | _Function_ | - |
|
||||||
| before-delete | Hook before delete the file, return false to stop reading the file, can return Promise | _Function_ | - |
|
| before-delete | Hook before delete the file, return false to stop reading the file, can return Promise | _Function_ | - |
|
||||||
| max-size | Max size of file | _number \| string_ | - |
|
| max-size `v3.0.17` | Max size of file | _number \| string \| (file: File) => boolean_ | - |
|
||||||
| max-count | Max count of image | _number \| string_ | - |
|
| max-count | Max count of image | _number \| string_ | - |
|
||||||
| result-type | Type of file read result, can be set to `file` `text` | _string_ | `dataUrl` |
|
| result-type | Type of file read result, can be set to `file` `text` | _string_ | `dataUrl` |
|
||||||
| upload-text | Upload text | _string_ | - |
|
| upload-text | Upload text | _string_ | - |
|
||||||
@ -308,7 +330,7 @@ export default {
|
|||||||
| default | Custom icon | - |
|
| default | Custom icon | - |
|
||||||
| preview-cover | Custom content that covers the image preview | `item: FileListItem` |
|
| preview-cover | Custom content that covers the image preview | `item: FileListItem` |
|
||||||
|
|
||||||
### Parematers of before-read、after-read、before-delete
|
### Parameters of before-read、after-read、before-delete
|
||||||
|
|
||||||
| Attribute | Description | Type |
|
| Attribute | Description | Type |
|
||||||
| --------- | ------------------------------------ | -------- |
|
| --------- | ------------------------------------ | -------- |
|
||||||
|
@ -159,6 +159,28 @@ export default {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
如果需要针对不同类型的文件来作出不同的大小限制,可以在 `max-size` 属性中传入一个函数,在函数中通过 `file.type` 区分文件类型,返回 `true` 表示超出限制,`false` 表示未超出限制。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-uploader multiple :max-size="isOverSize" />
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Toast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const isOverSize = (file) => {
|
||||||
|
const maxSize = file.type === 'image/jpeg' ? 500 * 1024 : 1000 * 1024;
|
||||||
|
return file.size >= maxSize;
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
isOverSize,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### 自定义上传样式
|
### 自定义上传样式
|
||||||
|
|
||||||
通过默认插槽可以自定义上传区域的样式。
|
通过默认插槽可以自定义上传区域的样式。
|
||||||
@ -306,7 +328,7 @@ export default {
|
|||||||
| after-read | 文件读取完成后的回调函数 | _Function_ | - |
|
| after-read | 文件读取完成后的回调函数 | _Function_ | - |
|
||||||
| before-read | 文件读取前的回调函数,返回 `false` 可终止文件读取,<br>支持返回 `Promise` | _Function_ | - |
|
| before-read | 文件读取前的回调函数,返回 `false` 可终止文件读取,<br>支持返回 `Promise` | _Function_ | - |
|
||||||
| before-delete | 文件删除前的回调函数,返回 `false` 可终止文件读取,<br>支持返回 `Promise` | _Function_ | - |
|
| before-delete | 文件删除前的回调函数,返回 `false` 可终止文件读取,<br>支持返回 `Promise` | _Function_ | - |
|
||||||
| max-size | 文件大小限制,单位为 `byte` | _number \| string_ | - |
|
| max-size `v3.0.17` | 文件大小限制,单位为 `byte` | _number \| string \| (file: File) => boolean_ | - |
|
||||||
| max-count | 文件上传数量限制 | _number \| string_ | - |
|
| max-count | 文件上传数量限制 | _number \| string_ | - |
|
||||||
| result-type | 文件读取结果类型,可选值为 `file` `text` | _string_ | `dataUrl` |
|
| result-type | 文件读取结果类型,可选值为 `file` `text` | _string_ | `dataUrl` |
|
||||||
| upload-text | 上传区域文字提示 | _string_ | - |
|
| upload-text | 上传区域文字提示 | _string_ | - |
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
filterFiles,
|
filterFiles,
|
||||||
isImageFile,
|
isImageFile,
|
||||||
readFileContent,
|
readFileContent,
|
||||||
|
UploaderMaxSize,
|
||||||
UploaderResultType,
|
UploaderResultType,
|
||||||
UploaderFileListItem,
|
UploaderFileListItem,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
@ -83,7 +84,7 @@ export default defineComponent({
|
|||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
maxSize: {
|
maxSize: {
|
||||||
type: [Number, String],
|
type: [Number, String, Function] as PropType<UploaderMaxSize>,
|
||||||
default: Number.MAX_VALUE,
|
default: Number.MAX_VALUE,
|
||||||
},
|
},
|
||||||
maxCount: {
|
maxCount: {
|
||||||
|
@ -3,7 +3,9 @@ import Uploader, { UploaderFileListItem } from '..';
|
|||||||
import { mount, later, triggerDrag } from '../../../test';
|
import { mount, later, triggerDrag } from '../../../test';
|
||||||
|
|
||||||
const mockFileDataUrl = 'data:image/test';
|
const mockFileDataUrl = 'data:image/test';
|
||||||
const mockFile = new File([new ArrayBuffer(10000)], 'test.jpg');
|
const mockFile = new File([new ArrayBuffer(10000)], 'test.jpg', {
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
const IMAGE = 'https://img.yzcdn.cn/vant/cat.jpeg';
|
const IMAGE = 'https://img.yzcdn.cn/vant/cat.jpeg';
|
||||||
const PDF = 'https://img.yzcdn.cn/vant/test.pdf';
|
const PDF = 'https://img.yzcdn.cn/vant/test.pdf';
|
||||||
|
|
||||||
@ -218,7 +220,7 @@ test('before read return promise and reject', async () => {
|
|||||||
expect(input.element.value).toEqual('');
|
expect(input.element.value).toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('file size overlimit', async () => {
|
test('should trigger oversize event when file size is overlimit', async () => {
|
||||||
const wrapper = mount(Uploader, {
|
const wrapper = mount(Uploader, {
|
||||||
props: {
|
props: {
|
||||||
maxSize: 1,
|
maxSize: 1,
|
||||||
@ -250,6 +252,31 @@ test('file size overlimit', async () => {
|
|||||||
expect(wrapper.emitted<[File]>('oversize')![2]).toBeFalsy();
|
expect(wrapper.emitted<[File]>('oversize')![2]).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should allow to custom max-size for different type of files', async () => {
|
||||||
|
const wrapper = mount(Uploader, {
|
||||||
|
props: {
|
||||||
|
maxSize(file: File) {
|
||||||
|
if (file.type === 'test') {
|
||||||
|
return file.size > 500;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
|
||||||
|
const fileList = [mockFile];
|
||||||
|
|
||||||
|
Object.defineProperty(input.element, 'files', {
|
||||||
|
get: () => jest.fn().mockReturnValue(fileList)(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await input.trigger('change');
|
||||||
|
|
||||||
|
await later();
|
||||||
|
expect(wrapper.emitted<[File]>('oversize')![0]).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
test('render upload-text', () => {
|
test('render upload-text', () => {
|
||||||
const uploadText = 'Text';
|
const uploadText = 'Text';
|
||||||
const wrapper = mount(Uploader, {
|
const wrapper = mount(Uploader, {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { createNamespace } from '../utils';
|
import { createNamespace, isFunction } from '../utils';
|
||||||
import type { ImageFit } from '../image';
|
import type { ImageFit } from '../image';
|
||||||
import type { Interceptor } from '../utils/interceptor';
|
import type { Interceptor } from '../utils/interceptor';
|
||||||
|
|
||||||
@ -21,6 +21,8 @@ export type UploaderFileListItem = {
|
|||||||
beforeDelete?: Interceptor;
|
beforeDelete?: Interceptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type UploaderMaxSize = number | string | ((file: File) => boolean);
|
||||||
|
|
||||||
export function toArray<T>(item: T | T[]): T[] {
|
export function toArray<T>(item: T | T[]): T[] {
|
||||||
if (Array.isArray(item)) {
|
if (Array.isArray(item)) {
|
||||||
return item;
|
return item;
|
||||||
@ -52,20 +54,28 @@ export function readFileContent(file: File, resultType: UploaderResultType) {
|
|||||||
|
|
||||||
export function isOversize(
|
export function isOversize(
|
||||||
items: UploaderFileListItem | UploaderFileListItem[],
|
items: UploaderFileListItem | UploaderFileListItem[],
|
||||||
maxSize: number | string
|
maxSize: UploaderMaxSize
|
||||||
): boolean {
|
): boolean {
|
||||||
return toArray(items).some((item) => item.file && item.file.size > maxSize);
|
return toArray(items).some((item) => {
|
||||||
|
if (item.file) {
|
||||||
|
if (isFunction(maxSize)) {
|
||||||
|
return maxSize(item.file);
|
||||||
|
}
|
||||||
|
return item.file.size > maxSize;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterFiles(
|
export function filterFiles(
|
||||||
items: UploaderFileListItem[],
|
items: UploaderFileListItem[],
|
||||||
maxSize: number | string
|
maxSize: UploaderMaxSize
|
||||||
) {
|
) {
|
||||||
const valid: UploaderFileListItem[] = [];
|
const valid: UploaderFileListItem[] = [];
|
||||||
const invalid: UploaderFileListItem[] = [];
|
const invalid: UploaderFileListItem[] = [];
|
||||||
|
|
||||||
items.forEach((item) => {
|
items.forEach((item) => {
|
||||||
if (item.file && item.file.size > maxSize) {
|
if (isOversize(item, maxSize)) {
|
||||||
invalid.push(item);
|
invalid.push(item);
|
||||||
} else {
|
} else {
|
||||||
valid.push(item);
|
valid.push(item);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user