mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(Uploader): expose reuploadFile method (#13012)
This commit is contained in:
parent
3a4c4a35ec
commit
33662b3dea
@ -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
|
||||||
|
|
||||||
|
@ -416,6 +416,7 @@ before-read、after-read、before-delete 执行时会传递以下回调参数:
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| closeImagePreview | 关闭全屏的图片预览 | - | - |
|
| closeImagePreview | 关闭全屏的图片预览 | - | - |
|
||||||
| chooseFile | 主动调起文件选择,由于浏览器安全限制,只有在用户触发操作的上下文中调用才有效 | - | - |
|
| chooseFile | 主动调起文件选择,由于浏览器安全限制,只有在用户触发操作的上下文中调用才有效 | - | - |
|
||||||
|
| reuploadFile `4.9.3` | 主动调起文件选择,选择新文件后将覆盖原先上传的文件,由于浏览器安全限制,只有在用户触发操作的上下文中调用才有效 | _index: number_ | - |
|
||||||
|
|
||||||
### 类型定义
|
### 类型定义
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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 },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
@ -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<
|
||||||
|
Loading…
x
Reference in New Issue
Block a user