feat(Uploader): expose reuploadFile method (#13012)

This commit is contained in:
inottn 2024-07-21 17:43:39 +08:00 committed by GitHub
parent 3a4c4a35ec
commit 33662b3dea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 45 additions and 13 deletions

View File

@ -393,6 +393,7 @@ Use [ref](https://vuejs.org/guide/essentials/template-refs.html) to get Uploader
| --- | --- | --- | --- | | --- | --- | --- | --- |
| closeImagePreview | Close full screen image preview | - | - | | closeImagePreview | Close full screen image preview | - | - |
| chooseFile | Trigger choosing files, works with the user action context only because of browser security | - | - | | chooseFile | Trigger choosing files, works with the user action context only because of browser security | - | - |
| reuploadFile `4.9.3` | Trigger choosing files, choosing a new file will overwrite the previously uploaded file, works with the user action context only because of browser security | _index: number_ | - |
### Types ### Types

View File

@ -416,6 +416,7 @@ before-read、after-read、before-delete 执行时会传递以下回调参数:
| --- | --- | --- | --- | | --- | --- | --- | --- |
| closeImagePreview | 关闭全屏的图片预览 | - | - | | closeImagePreview | 关闭全屏的图片预览 | - | - |
| chooseFile | 主动调起文件选择,由于浏览器安全限制,只有在用户触发操作的上下文中调用才有效 | - | - | | chooseFile | 主动调起文件选择,由于浏览器安全限制,只有在用户触发操作的上下文中调用才有效 | - | - |
| reuploadFile `4.9.3` | 主动调起文件选择,选择新文件后将覆盖原先上传的文件,由于浏览器安全限制,只有在用户触发操作的上下文中调用才有效 | _index: number_ | - |
### 类型定义 ### 类型定义

View File

@ -279,11 +279,12 @@ export default defineComponent({
emit('delete', item, getDetail(index)); emit('delete', item, getDetail(index));
}; };
const reuploadImage = (index: number) => { const reuploadFile = (index: number) => {
isReuploading.value = true; isReuploading.value = true;
reuploadIndex.value = index; reuploadIndex.value = index;
nextTick(() => chooseFile()); nextTick(() => chooseFile());
}; };
const onInputClick = () => { const onInputClick = () => {
if (!isReuploading.value) { if (!isReuploading.value) {
reuploadIndex.value = -1; reuploadIndex.value = -1;
@ -319,7 +320,7 @@ export default defineComponent({
} }
onDelete={() => deleteFile(item, index)} onDelete={() => deleteFile(item, index)}
onPreview={() => previewImage(item)} onPreview={() => previewImage(item)}
onReupload={() => reuploadImage(index)} onReupload={() => reuploadFile(index)}
{...pick(props, ['name', 'lazyLoad'])} {...pick(props, ['name', 'lazyLoad'])}
{...previewData} {...previewData}
/> />
@ -335,12 +336,7 @@ export default defineComponent({
const onClickUpload = (event: MouseEvent) => emit('clickUpload', event); const onClickUpload = (event: MouseEvent) => emit('clickUpload', event);
const renderUpload = () => { const renderUpload = () => {
if (props.modelValue.length >= +props.maxCount && !props.reupload) { const lessThanMax = props.modelValue.length < +props.maxCount;
return;
}
const hideUploader =
props.modelValue.length >= +props.maxCount && props.reupload;
const Input = props.readonly ? null : ( const Input = props.readonly ? null : (
<input <input
@ -359,7 +355,7 @@ export default defineComponent({
if (slots.default) { if (slots.default) {
return ( return (
<div <div
v-show={!hideUploader} v-show={lessThanMax}
class={bem('input-wrapper')} class={bem('input-wrapper')}
onClick={onClickUpload} onClick={onClickUpload}
> >
@ -371,7 +367,7 @@ export default defineComponent({
return ( return (
<div <div
v-show={props.showUpload && !hideUploader} v-show={props.showUpload && lessThanMax}
class={bem('upload', { readonly: props.readonly })} class={bem('upload', { readonly: props.readonly })}
style={getSizeStyle(props.previewSize)} style={getSizeStyle(props.previewSize)}
onClick={onClickUpload} onClick={onClickUpload}
@ -397,6 +393,7 @@ export default defineComponent({
useExpose<UploaderExpose>({ useExpose<UploaderExpose>({
chooseFile, chooseFile,
reuploadFile,
closeImagePreview, closeImagePreview,
}); });
useCustomFieldValue(() => props.modelValue); useCustomFieldValue(() => props.modelValue);

View File

@ -1,6 +1,6 @@
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { cdnURL } from '../../../docs/site'; import { cdnURL } from '../../../docs/site';
import Uploader, { type UploaderFileListItem } from '..'; import Uploader, { type UploaderFileListItem, type UploaderInstance } from '..';
import { mount, later, triggerDrag, trigger } from '../../../test'; import { mount, later, triggerDrag, trigger } from '../../../test';
import type { Numeric } from '../../utils'; import type { Numeric } from '../../utils';
@ -686,11 +686,10 @@ test('should emit clickReUpload event when props reupload true', async () => {
props: { props: {
maxCount: 1, maxCount: 1,
modelValue: [{ url: IMAGE }], modelValue: [{ url: IMAGE }],
reupload: true,
}, },
}); });
expect(wrapper.find('.van-uploader__upload').exists()).toBeFalsy();
await wrapper.setProps({ reupload: true });
expect(wrapper.find('.van-uploader__upload').style.display).toBe('none'); expect(wrapper.find('.van-uploader__upload').style.display).toBe('none');
const previewItem = wrapper.find<HTMLDivElement>( const previewItem = wrapper.find<HTMLDivElement>(
@ -706,3 +705,36 @@ test('should emit clickReUpload event when props reupload true', async () => {
await trigger(input, 'change'); await trigger(input, 'change');
expect(wrapper.emitted('update:modelValue')?.[0][0]).toHaveLength(1); expect(wrapper.emitted('update:modelValue')?.[0][0]).toHaveLength(1);
}); });
test('expose reuploadFile method', async () => {
const onUpdate = vi.fn();
const wrapper = mount(Uploader, {
props: {
maxCount: 2,
modelValue: [{ url: IMAGE }, { url: PDF }],
'onUpdate:modelValue': onUpdate,
},
});
const {reuploadFile} = (wrapper.vm as UploaderInstance);
expect(reuploadFile).toBeTypeOf('function');
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: vi.fn().mockReturnValue([mockFile]),
});
reuploadFile(1);
await trigger(input, 'change');
expect(onUpdate.mock.calls[0][0]).toMatchObject([
{ url: IMAGE },
{ file: mockFile },
]);
reuploadFile(0);
await trigger(input, 'change');
expect(onUpdate.mock.calls[1][0]).toMatchObject([
{ file: mockFile },
{ url: PDF },
]);
});

View File

@ -41,6 +41,7 @@ export type UploaderAfterRead = (
export type UploaderExpose = { export type UploaderExpose = {
chooseFile: () => void; chooseFile: () => void;
closeImagePreview: () => void; closeImagePreview: () => void;
reuploadFile: (index: number) => void;
}; };
export type UploaderInstance = ComponentPublicInstance< export type UploaderInstance = ComponentPublicInstance<