refactor: 文件/图片上传重构
This commit is contained in:
parent
dd57e3c9ae
commit
ffcc21975e
@ -7,22 +7,6 @@ import { requestClient } from '#/api/request';
|
|||||||
*/
|
*/
|
||||||
export type AxiosProgressEvent = AxiosRequestConfig['onUploadProgress'];
|
export type AxiosProgressEvent = AxiosRequestConfig['onUploadProgress'];
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过单文件上传接口
|
|
||||||
* @param file 上传的文件
|
|
||||||
* @param onUploadProgress 上传进度事件 非必传
|
|
||||||
* @returns 上传结果
|
|
||||||
*/
|
|
||||||
export function uploadApi(
|
|
||||||
file: Blob | File,
|
|
||||||
onUploadProgress?: AxiosProgressEvent,
|
|
||||||
) {
|
|
||||||
return requestClient.upload(
|
|
||||||
'/resource/oss/upload',
|
|
||||||
{ file },
|
|
||||||
{ onUploadProgress, timeout: 60_000 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 默认上传结果
|
* 默认上传结果
|
||||||
*/
|
*/
|
||||||
@ -31,3 +15,27 @@ export interface UploadResult {
|
|||||||
fileName: string;
|
fileName: string;
|
||||||
ossId: string;
|
ossId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过单文件上传接口
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @param otherData 其他请求参数 后端拓展可能会用到
|
||||||
|
* @param onUploadProgress 上传进度事件 非必传
|
||||||
|
* @returns 上传结果
|
||||||
|
*/
|
||||||
|
export function uploadApi(
|
||||||
|
file: Blob | File,
|
||||||
|
otherData?: Record<string, any>,
|
||||||
|
onUploadProgress?: AxiosProgressEvent,
|
||||||
|
) {
|
||||||
|
return requestClient.upload<UploadResult>(
|
||||||
|
'/resource/oss/upload',
|
||||||
|
{ file, ...otherData },
|
||||||
|
{ onUploadProgress, timeout: 60_000 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传api type
|
||||||
|
*/
|
||||||
|
export type UploadApi = typeof uploadApi;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { UploadFile } from 'ant-design-vue';
|
import type { UploadFile } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import type { BaseUploadProps } from './props';
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { $t, I18nT } from '@vben/locales';
|
import { $t, I18nT } from '@vben/locales';
|
||||||
@ -12,68 +14,26 @@ import { $t, I18nT } from '@vben/locales';
|
|||||||
import { InboxOutlined, UploadOutlined } from '@ant-design/icons-vue';
|
import { InboxOutlined, UploadOutlined } from '@ant-design/icons-vue';
|
||||||
import { Upload } from 'ant-design-vue';
|
import { Upload } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { uploadApi } from '#/api';
|
||||||
|
|
||||||
import { defaultFileAcceptExts, defaultFilePreview } from './helper';
|
import { defaultFileAcceptExts, defaultFilePreview } from './helper';
|
||||||
import { useUpload } from './hook';
|
import { useUpload } from './hook';
|
||||||
|
|
||||||
interface Props {
|
interface FileUploadProps extends BaseUploadProps {
|
||||||
/**
|
|
||||||
* 文件上传失败 是否从展示列表中删除
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
removeOnError?: boolean;
|
|
||||||
/**
|
|
||||||
* 上传成功 是否展示提示信息
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
showSuccessMsg?: boolean;
|
|
||||||
/**
|
|
||||||
* 删除文件前是否需要确认
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
removeConfirm?: boolean;
|
|
||||||
/**
|
|
||||||
* 同antdv参数
|
|
||||||
*/
|
|
||||||
accept?: string;
|
|
||||||
/**
|
|
||||||
* 附带的请求参数
|
|
||||||
*/
|
|
||||||
data?: any;
|
|
||||||
/**
|
|
||||||
* 最大上传图片数量
|
|
||||||
* maxCount为1时 会被绑定为string而非string[]
|
|
||||||
* @default 1
|
|
||||||
*/
|
|
||||||
maxCount?: number;
|
|
||||||
/**
|
|
||||||
* 文件最大 单位M
|
|
||||||
* @default 5
|
|
||||||
*/
|
|
||||||
maxSize?: number;
|
|
||||||
/**
|
|
||||||
* 是否禁用
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
disabled?: boolean;
|
|
||||||
/**
|
|
||||||
* 是否显示文案 请上传不超过...
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
helpMessage?: boolean;
|
|
||||||
/**
|
|
||||||
* 是否支持多选文件,ie10+ 支持。开启后按住 ctrl 可选择多个文件。
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
multiple?: boolean;
|
|
||||||
/**
|
/**
|
||||||
* 自定义文件预览逻辑 比如: 你可以改为下载
|
* 自定义文件预览逻辑 比如: 你可以改为下载
|
||||||
* @param file file
|
* @param file file
|
||||||
*/
|
*/
|
||||||
preview?: (file: UploadFile) => Promise<void> | void;
|
preview?: (file: UploadFile) => Promise<void> | void;
|
||||||
|
/**
|
||||||
|
* 是否支持拖拽上传
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
enableDragUpload?: boolean;
|
enableDragUpload?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<FileUploadProps>(), {
|
||||||
|
api: () => uploadApi,
|
||||||
removeOnError: true,
|
removeOnError: true,
|
||||||
showSuccessMsg: true,
|
showSuccessMsg: true,
|
||||||
removeConfirm: false,
|
removeConfirm: false,
|
||||||
@ -84,8 +44,11 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
helpMessage: true,
|
helpMessage: true,
|
||||||
preview: defaultFilePreview,
|
preview: defaultFilePreview,
|
||||||
|
enableDragUpload: false,
|
||||||
|
directory: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** 返回不同的上传组件 */
|
||||||
const CurrentUploadComponent = computed(() => {
|
const CurrentUploadComponent = computed(() => {
|
||||||
if (props.enableDragUpload) {
|
if (props.enableDragUpload) {
|
||||||
return Upload.Dragger;
|
return Upload.Dragger;
|
||||||
@ -99,8 +62,7 @@ const ossIdList = defineModel<string | string[]>('value', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
uploadUrl,
|
customRequest,
|
||||||
headers,
|
|
||||||
acceptFormat,
|
acceptFormat,
|
||||||
handleChange,
|
handleChange,
|
||||||
handleRemove,
|
handleRemove,
|
||||||
@ -113,15 +75,14 @@ const {
|
|||||||
<div>
|
<div>
|
||||||
<CurrentUploadComponent
|
<CurrentUploadComponent
|
||||||
v-model:file-list="innerFileList"
|
v-model:file-list="innerFileList"
|
||||||
:action="uploadUrl"
|
|
||||||
:headers="headers"
|
|
||||||
:data="data"
|
|
||||||
:accept="accept"
|
:accept="accept"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
|
:directory="directory"
|
||||||
:max-count="maxCount"
|
:max-count="maxCount"
|
||||||
:progress="{ showInfo: true }"
|
:progress="{ showInfo: true }"
|
||||||
:multiple="multiple"
|
:multiple="multiple"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
|
:custom-request="customRequest"
|
||||||
@preview="preview"
|
@preview="preview"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
@remove="handleRemove"
|
@remove="handleRemove"
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import type { UploadChangeParam, UploadFile } from 'ant-design-vue';
|
import type { UploadChangeParam, UploadFile } from 'ant-design-vue';
|
||||||
import type { FileType } from 'ant-design-vue/es/upload/interface';
|
import type { FileType } from 'ant-design-vue/es/upload/interface';
|
||||||
|
import type { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
|
||||||
|
|
||||||
import type { ModelRef } from 'vue';
|
import type { ModelRef } from 'vue';
|
||||||
|
|
||||||
import type { HttpResponse } from '@vben/request';
|
import type { BaseUploadProps } from './props';
|
||||||
|
|
||||||
import type { UploadResult } from '#/api';
|
import type { AxiosProgressEvent, UploadResult } from '#/api';
|
||||||
import type { OssFile } from '#/api/system/oss/model';
|
import type { OssFile } from '#/api/system/oss/model';
|
||||||
|
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
import { useAppConfig } from '@vben/hooks';
|
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
import { useAccessStore } from '@vben/stores';
|
|
||||||
|
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
|
import { isFunction } from 'lodash-es';
|
||||||
|
|
||||||
import { ossInfo } from '#/api/system/oss';
|
import { ossInfo } from '#/api/system/oss';
|
||||||
|
|
||||||
@ -85,29 +85,9 @@ export function useUpload(
|
|||||||
props: Readonly<BaseUploadProps>,
|
props: Readonly<BaseUploadProps>,
|
||||||
bindValue: ModelRef<string | string[]>,
|
bindValue: ModelRef<string | string[]>,
|
||||||
) {
|
) {
|
||||||
const { apiURL, clientId } = useAppConfig(
|
// 组件内部维护fileList
|
||||||
import.meta.env,
|
|
||||||
import.meta.env.PROD,
|
|
||||||
);
|
|
||||||
|
|
||||||
// 内部维护fileList
|
|
||||||
const innerFileList = ref<UploadFile[]>([]);
|
const innerFileList = ref<UploadFile[]>([]);
|
||||||
|
|
||||||
/** oss上传地址 */
|
|
||||||
const uploadUrl = `${apiURL}/resource/oss/upload`;
|
|
||||||
|
|
||||||
const accessStore = useAccessStore();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* header参数 需要带上token和clientId
|
|
||||||
*/
|
|
||||||
const headers = computed(() => {
|
|
||||||
return {
|
|
||||||
Authorization: `Bearer ${accessStore.accessToken}`,
|
|
||||||
clientId,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const acceptFormat = computed(() => {
|
const acceptFormat = computed(() => {
|
||||||
return props.accept
|
return props.accept
|
||||||
?.split(',')
|
?.split(',')
|
||||||
@ -121,6 +101,11 @@ export function useUpload(
|
|||||||
});
|
});
|
||||||
|
|
||||||
function handleChange(info: UploadChangeParam) {
|
function handleChange(info: UploadChangeParam) {
|
||||||
|
/**
|
||||||
|
* 移除当前文件
|
||||||
|
* @param currentFile 当前文件
|
||||||
|
* @param currentFileList 当前所有文件list
|
||||||
|
*/
|
||||||
function removeCurrentFile(
|
function removeCurrentFile(
|
||||||
currentFile: UploadChangeParam['file'],
|
currentFile: UploadChangeParam['file'],
|
||||||
currentFileList: UploadChangeParam['fileList'],
|
currentFileList: UploadChangeParam['fileList'],
|
||||||
@ -140,19 +125,9 @@ export function useUpload(
|
|||||||
if (!currentFile.response) {
|
if (!currentFile.response) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 获取返回结果
|
// 获取返回结果 为customRequest的reslove参数
|
||||||
const response = currentFile.response as HttpResponse<UploadResult>;
|
// 只有success才会走到这里
|
||||||
// 上传异常
|
const { ossId, fileName, url } = currentFile.response as UploadResult;
|
||||||
if (response.code !== 200) {
|
|
||||||
message.error(response.msg);
|
|
||||||
removeCurrentFile(currentFile, fileList);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 上传成功 做转换
|
|
||||||
if (props.showSuccessMsg) {
|
|
||||||
message.success($t('component.upload.uploadSuccess'));
|
|
||||||
}
|
|
||||||
const { ossId, fileName, url } = response.data;
|
|
||||||
currentFile.url = url;
|
currentFile.url = url;
|
||||||
currentFile.fileName = fileName;
|
currentFile.fileName = fileName;
|
||||||
currentFile.uid = ossId;
|
currentFile.uid = ossId;
|
||||||
@ -166,7 +141,6 @@ export function useUpload(
|
|||||||
}
|
}
|
||||||
// 上传失败 网络原因导致httpStatus 不等于200
|
// 上传失败 网络原因导致httpStatus 不等于200
|
||||||
case 'error': {
|
case 'error': {
|
||||||
message.error($t('component.upload.uploadError'));
|
|
||||||
removeCurrentFile(currentFile, fileList);
|
removeCurrentFile(currentFile, fileList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,6 +181,12 @@ export function useUpload(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传前检测文件大小
|
||||||
|
* 拖拽时候前置会有浏览器自身的accept校验 校验失败不会执行此方法
|
||||||
|
* @param file file
|
||||||
|
* @returns file | false
|
||||||
|
*/
|
||||||
function beforeUpload(file: FileType) {
|
function beforeUpload(file: FileType) {
|
||||||
const isLtMax = file.size / 1024 / 1024 < props.maxSize!;
|
const isLtMax = file.size / 1024 / 1024 < props.maxSize!;
|
||||||
if (!isLtMax) {
|
if (!isLtMax) {
|
||||||
@ -217,6 +197,37 @@ export function useUpload(
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义上传实现
|
||||||
|
* @param info
|
||||||
|
*/
|
||||||
|
async function customRequest(info: UploadRequestOption<any>) {
|
||||||
|
const { api } = props;
|
||||||
|
if (!isFunction(api)) {
|
||||||
|
console.warn('upload api must exist and be a function');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 进度条事件
|
||||||
|
const progressEvent: AxiosProgressEvent = (e) => {
|
||||||
|
const percent = Math.trunc((e.loaded / e.total!) * 100);
|
||||||
|
info.onProgress!({ percent });
|
||||||
|
};
|
||||||
|
const res = await api(
|
||||||
|
info.file as File,
|
||||||
|
props?.data ?? {},
|
||||||
|
progressEvent,
|
||||||
|
);
|
||||||
|
info.onSuccess!(res);
|
||||||
|
if (props.showSuccessMsg) {
|
||||||
|
message.success($t('component.upload.uploadSuccess'));
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(error);
|
||||||
|
info.onError!(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 这里只监听list地址变化 即重新赋值才会触发watch
|
* 这里只监听list地址变化 即重新赋值才会触发watch
|
||||||
* immediate用于初始化触发
|
* immediate用于初始化触发
|
||||||
@ -244,11 +255,10 @@ export function useUpload(
|
|||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
uploadUrl,
|
|
||||||
headers,
|
|
||||||
handleChange,
|
handleChange,
|
||||||
handleRemove,
|
handleRemove,
|
||||||
beforeUpload,
|
beforeUpload,
|
||||||
|
customRequest,
|
||||||
innerFileList,
|
innerFileList,
|
||||||
acceptFormat,
|
acceptFormat,
|
||||||
};
|
};
|
||||||
|
@ -5,72 +5,28 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { UploadListType } from 'ant-design-vue/es/upload/interface';
|
import type { UploadListType } from 'ant-design-vue/es/upload/interface';
|
||||||
|
|
||||||
|
import type { BaseUploadProps } from './props';
|
||||||
|
|
||||||
import { $t, I18nT } from '@vben/locales';
|
import { $t, I18nT } from '@vben/locales';
|
||||||
|
|
||||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||||
import { Image, ImagePreviewGroup, Upload } from 'ant-design-vue';
|
import { Image, ImagePreviewGroup, Upload } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { uploadApi } from '#/api';
|
||||||
|
|
||||||
import { defaultImageAcceptExts } from './helper';
|
import { defaultImageAcceptExts } from './helper';
|
||||||
import { useImagePreview, useUpload } from './hook';
|
import { useImagePreview, useUpload } from './hook';
|
||||||
|
|
||||||
interface Props {
|
interface ImageUploadProps extends BaseUploadProps {
|
||||||
/**
|
|
||||||
* 文件上传失败 是否从展示列表中删除
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
removeOnError?: boolean;
|
|
||||||
/**
|
|
||||||
* 上传成功 是否展示提示信息
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
showSuccessMsg?: boolean;
|
|
||||||
/**
|
|
||||||
* 删除文件前是否需要确认
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
removeConfirm?: boolean;
|
|
||||||
/**
|
|
||||||
* 同antdv参数
|
|
||||||
*/
|
|
||||||
accept?: string;
|
|
||||||
/**
|
|
||||||
* 附带的请求参数
|
|
||||||
*/
|
|
||||||
data?: any;
|
|
||||||
/**
|
|
||||||
* 最大上传图片数量
|
|
||||||
* maxCount为1时 会被绑定为string而非string[]
|
|
||||||
* @default 1
|
|
||||||
*/
|
|
||||||
maxCount?: number;
|
|
||||||
/**
|
|
||||||
* 文件最大 单位M
|
|
||||||
* @default 5
|
|
||||||
*/
|
|
||||||
maxSize?: number;
|
|
||||||
/**
|
|
||||||
* 是否禁用
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
disabled?: boolean;
|
|
||||||
/**
|
/**
|
||||||
* 同antdv的listType
|
* 同antdv的listType
|
||||||
* @default picture-card
|
* @default picture-card
|
||||||
*/
|
*/
|
||||||
listType?: UploadListType;
|
listType?: UploadListType;
|
||||||
/**
|
|
||||||
* 是否显示文案 请上传不超过...
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
helpMessage?: boolean;
|
|
||||||
/**
|
|
||||||
* 是否支持多选文件,ie10+ 支持。开启后按住 ctrl 可选择多个文件。
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
multiple?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<ImageUploadProps>(), {
|
||||||
|
api: () => uploadApi,
|
||||||
removeOnError: true,
|
removeOnError: true,
|
||||||
showSuccessMsg: true,
|
showSuccessMsg: true,
|
||||||
removeConfirm: false,
|
removeConfirm: false,
|
||||||
@ -89,13 +45,12 @@ const ossIdList = defineModel<string | string[]>('value', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
uploadUrl,
|
|
||||||
headers,
|
|
||||||
acceptFormat,
|
acceptFormat,
|
||||||
handleChange,
|
handleChange,
|
||||||
handleRemove,
|
handleRemove,
|
||||||
beforeUpload,
|
beforeUpload,
|
||||||
innerFileList,
|
innerFileList,
|
||||||
|
customRequest,
|
||||||
} = useUpload(props, ossIdList);
|
} = useUpload(props, ossIdList);
|
||||||
|
|
||||||
const { previewVisible, previewImage, handleCancel, handlePreview } =
|
const { previewVisible, previewImage, handleCancel, handlePreview } =
|
||||||
@ -107,15 +62,14 @@ const { previewVisible, previewImage, handleCancel, handlePreview } =
|
|||||||
<Upload
|
<Upload
|
||||||
v-model:file-list="innerFileList"
|
v-model:file-list="innerFileList"
|
||||||
:list-type="listType"
|
:list-type="listType"
|
||||||
:action="uploadUrl"
|
|
||||||
:headers="headers"
|
|
||||||
:data="data"
|
|
||||||
:accept="accept"
|
:accept="accept"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
|
:directory="directory"
|
||||||
:max-count="maxCount"
|
:max-count="maxCount"
|
||||||
:progress="{ showInfo: true }"
|
:progress="{ showInfo: true }"
|
||||||
:multiple="multiple"
|
:multiple="multiple"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
|
:custom-request="customRequest"
|
||||||
@preview="handlePreview"
|
@preview="handlePreview"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
@remove="handleRemove"
|
@remove="handleRemove"
|
||||||
|
@ -19,4 +19,8 @@ return new Promise<FileType>((resolve) =>
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
根本原因在于`file-typ`库可能不支持Safari 去掉可以正常上传
|
根本原因在于`file-typ`库的`fileTypeFromBlob`方法不支持Safari 去掉可以正常上传
|
||||||
|
|
||||||
|
safari不支持`ReadableStreamBYOBReader`api
|
||||||
|
|
||||||
|
详见: https://github.com/sindresorhus/file-type/issues/690
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
interface BaseUploadProps {
|
import type { UploadApi } from '#/api';
|
||||||
|
|
||||||
|
export interface BaseUploadProps {
|
||||||
|
/**
|
||||||
|
* 上传接口
|
||||||
|
*/
|
||||||
|
api?: UploadApi;
|
||||||
/**
|
/**
|
||||||
* 文件上传失败 是否从展示列表中删除
|
* 文件上传失败 是否从展示列表中删除
|
||||||
* @default true
|
* @default true
|
||||||
@ -48,4 +54,9 @@ interface BaseUploadProps {
|
|||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
|
/**
|
||||||
|
* 是否支持上传文件夹
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
directory?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import { Alert, Card, Modal } from 'ant-design-vue';
|
|||||||
|
|
||||||
import { FileUpload, ImageUpload } from '#/components/upload';
|
import { FileUpload, ImageUpload } from '#/components/upload';
|
||||||
|
|
||||||
const singleImageId = ref('1905537674682916865');
|
const singleImageId = ref('');
|
||||||
const singleFileId = ref('1905191167882518529');
|
const singleFileId = ref('1905191167882518529');
|
||||||
const multipleImageId = ref<string[]>(['1905537674682916865']);
|
const multipleImageId = ref<string[]>(['1905537674682916865']);
|
||||||
const multipleFileId = ref<string[]>(['1905191167882518529']);
|
const multipleFileId = ref<string[]>(['1905191167882518529']);
|
||||||
@ -74,6 +74,16 @@ function handlePreview(file: UploadFile) {
|
|||||||
<Card title="文件禁用上传" size="small">
|
<Card title="文件禁用上传" size="small">
|
||||||
<FileUpload :disabled="true" :max-count="3" :help-message="false" />
|
<FileUpload :disabled="true" :max-count="3" :help-message="false" />
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<Card title="文件夹上传" size="small">
|
||||||
|
<FileUpload
|
||||||
|
v-model:value="multipleFileId"
|
||||||
|
:max-count="3"
|
||||||
|
:directory="true"
|
||||||
|
accept="*"
|
||||||
|
/>
|
||||||
|
当前绑定值: {{ multipleFileId }}
|
||||||
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user