diff --git a/devui/upload/src/multiple-upload.tsx b/devui/upload/src/multiple-upload.tsx index da3a23157352bf820610386afb6b0361ca6b9015..0928fe4106b23878bb278236f0a9062e1de07173 100644 --- a/devui/upload/src/multiple-upload.tsx +++ b/devui/upload/src/multiple-upload.tsx @@ -1,8 +1,4 @@ -import './upload.scss' - import { defineComponent, toRefs, ref } from 'vue' -import { Observable } from 'rxjs' -import { last, map, debounceTime } from 'rxjs/operators' import { ToastService } from '../../toast' import { UploadStatus, multiUploadProps } from './upload-types' import { useSelectFiles } from './use-select-files' @@ -15,6 +11,7 @@ import { getExistSameNameFilesMsg, } from './i18n-upload' import { FileUploader } from './file-uploader' +import './upload.scss' export default defineComponent({ name: 'DMultipleUpload', @@ -98,38 +95,32 @@ export default defineComponent({ } } - const _dealFiles = (observale) => { + const _dealFiles = (promise: Promise) => { resetSameNameFiles() - observale - .pipe( - map((file) => { + promise + .then((files) => { + files.forEach((file) => { addFile(file, uploadOptions.value) - return file - }), - debounceTime(100) - ) - .subscribe( - () => { - checkValid() - const sameNameFiles = getSameNameFiles() - if (uploadOptions.value.checkSameName && sameNameFiles.length) { - alertMsg(getExistSameNameFilesMsg(sameNameFiles)) - } - // TODO: onChange事件 - const selectedFiles = fileUploaders.value - .filter( - (fileUploader) => fileUploader.status === UploadStatus.preLoad - ) - .map((fileUploader) => fileUploader.file) - ctx.emit('fileSelect', selectedFiles) - if (autoUpload.value) { - upload() - } - }, - (error: Error) => { - alertMsg(error.message) + // debounceTime(100) + }) + checkValid() + const sameNameFiles = getSameNameFiles() + if (uploadOptions.value.checkSameName && sameNameFiles.length) { + alertMsg(getExistSameNameFilesMsg(sameNameFiles)) } - ) + const selectedFiles = fileUploaders.value + .filter( + (fileUploader) => fileUploader.status === UploadStatus.preLoad + ) + .map((fileUploader) => fileUploader.file) + ctx.emit('fileSelect', selectedFiles) + if (autoUpload.value) { + upload() + } + }) + .catch((error: Error) => { + alertMsg(error.message) + }) } const handleClick = () => { @@ -141,9 +132,7 @@ export default defineComponent({ const onFileDrop = (files: File[]) => { isDropOVer.value = false - _dealFiles( - triggerDropFiles(fileOptions.value, uploadOptions.value, files) - ) + _dealFiles(triggerDropFiles(files)) ctx.emit('fileDrop', files) } const onFileOver = (event: boolean) => { @@ -169,8 +158,6 @@ export default defineComponent({ if (typeof result !== 'undefined') { if (result.then) { uploadResult = result - } else if (result.subscribe) { - uploadResult = (result as Observable).toPromise() } else { uploadResult = Promise.resolve(result) } @@ -190,17 +177,17 @@ export default defineComponent({ const uploadObservable = oneTimeUpload.value ? _oneTimeUpload() : upload(fileUploader) - uploadObservable.pipe(last()).subscribe( - (results: Array<{ file: File; response: any; }>) => { + + uploadObservable + .then((results: Array<{ file: File; response: any; }>) => { ctx.emit('successEvent', results) const newFiles = results.map((result) => result.file) const newUploadedFiles = [...newFiles, ...uploadedFiles.value] ctx.emit('update:uploadedFiles', newUploadedFiles) - }, - (error) => { + }) + .catch((error) => { ctx.emit('errorEvent', error) - } - ) + }) }) } @@ -301,82 +288,78 @@ export default defineComponent({ v-file-drop={{ enableDrop, isSingle: false, onFileDrop, onFileOver }} style={`border: ${isDropOVer ? '1px solid #15bf15' : '0'}`} > -
- {fileUploaders.length === 0 && ( -
- {placeholderText} -
- )} - {fileUploaders.length > 0 && ( -
    - {fileUploaders.map((fileUploader, index) => ( -
  • - {this.$slots.default()}
+ ) : ( +
+ {fileUploaders.length === 0 && ( +
+ {placeholderText} +
+ )} + {fileUploaders.length > 0 && ( +
    + {fileUploaders.map((fileUploader, index) => ( +
  • - {fileUploader.file.name} - - - onDeleteFile(event, fileUploader.file) - } - /> - {fileUploader.status === UploadStatus.uploading && ( -
    - -
    - )} - {fileUploader.status === UploadStatus.failed && ( - - )} - {fileUploader.status === UploadStatus.uploaded && ( - - )} -
  • - ))} -
- )} - - - - - -
+ + {fileUploader.file.name} + + + onDeleteFile(event, fileUploader.file) + } + /> + {fileUploader.status === UploadStatus.uploading && ( +
+ +
+ )} + {fileUploader.status === UploadStatus.failed && ( + + )} + {fileUploader.status === UploadStatus.uploaded && ( + + )} + + ))} + + )} + + + + + )} {!autoUpload && !withoutBtn && ( )} - {showTip && ( -
- {getStatus() === 'selected' && ( - {uploadTips} - )} - {getStatus() === 'uploading' && ( - - {uploadTips} - {i18nText.cancelUpload} - - )} - {getStatus() === 'uploaded' && ( -
- - - {i18nText.uploadSuccess} - -
- )} - {getStatus() === 'failed' && ( -
- - - {uploadTips} - {i18nText.reUpload} - -
- )} -
- )} + {}
{this.$slots.preloadFiles?.({ fileUploaders, diff --git a/devui/upload/src/single-upload-view.tsx b/devui/upload/src/single-upload-view.tsx deleted file mode 100644 index 33d4f981a6d4d9a19e3feff00da7b20cf01cffb8..0000000000000000000000000000000000000000 --- a/devui/upload/src/single-upload-view.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import './upload.scss' - -import { defineComponent } from 'vue' -import { singleUploadViewProps } from './upload-types' - -export default defineComponent({ - name: 'DSingleUploadView', - props: singleUploadViewProps, - // setup(props) {}, - render() { - const {} = this - return
- }, -}) diff --git a/devui/upload/src/single-upload.tsx b/devui/upload/src/single-upload.tsx index 9ceb1f5db15568daaa9e0c309e5865d135ef2631..23c84d49f3acb7b58a4bb3ea54e48a5790d5753b 100644 --- a/devui/upload/src/single-upload.tsx +++ b/devui/upload/src/single-upload.tsx @@ -1,13 +1,11 @@ -import './upload.scss' - import { defineComponent, toRefs, computed, ref } from 'vue' -import { Observable } from 'rxjs' -import { last, map } from 'rxjs/operators' import { ToastService } from '../../toast' import { uploadProps, UploadProps, UploadStatus } from './upload-types' import { useUpload } from './use-upload' import { useSelectFiles } from './use-select-files' import { i18nText } from './i18n-upload' +import './upload.scss' + export default defineComponent({ name: 'DSingleUpload', props: uploadProps, @@ -17,6 +15,7 @@ export default defineComponent({ 'fileSelect', 'successEvent', 'errorEvent', + 'deleteUploadedFileEvent', 'update:uploadedFiles', ], setup(props: UploadProps, ctx) { @@ -41,6 +40,7 @@ export default defineComponent({ getFullFiles, deleteFile, upload, + removeFiles, } = useUpload() const { triggerSelectFiles, _validateFiles, triggerDropFiles } = useSelectFiles() @@ -61,8 +61,6 @@ export default defineComponent({ if (typeof result !== 'undefined') { if (result.then) { uploadResult = result - } else if (result.subscribe) { - uploadResult = (result as Observable).toPromise() } else { uploadResult = Promise.resolve(result) } @@ -77,22 +75,19 @@ export default defineComponent({ return } upload() - .pipe(last()) - .subscribe( - (results: Array<{ file: File; response: any; }>) => { - ctx.emit('successEvent', results) - const newFiles = results.map((result) => result.file) - const newUploadedFiles = [...newFiles, ...uploadedFiles.value] - ctx.emit('update:uploadedFiles', newUploadedFiles) - }, - (error) => { - console.error(error) - if (fileUploaders.value[0]) { - fileUploaders.value[0].percentage = 0 - } - ctx.emit('errorEvent', error) + .then((results: { file: File; response: any; }[]) => { + ctx.emit('successEvent', results) + const newFiles = results.map((result) => result.file) + const newUploadedFiles = [...newFiles, ...uploadedFiles.value] + ctx.emit('update:uploadedFiles', newUploadedFiles) + }) + .catch((error) => { + console.error(error) + if (fileUploaders.value[0]) { + fileUploaders.value[0].percentage = 0 } - ) + ctx.emit('errorEvent', error) + }) }) } @@ -110,32 +105,29 @@ export default defineComponent({ }) } - const _dealFiles = (observale) => { - observale - .pipe( - map((file) => { + const _dealFiles = (promise: Promise) => { + promise + .then((files) => { + files.forEach((file) => { + // 单文件上传前先清空数组 + removeFiles() addFile(file, uploadOptions.value) - return file }) - ) - .subscribe( - () => { - checkValid() - const file = fileUploaders[0]?.file - if (props.onChange) { - props.onChange(file) - } - if (file) { - ctx.emit('fileSelect', file) - } - if (autoUpload.value) { - fileUpload() - } - }, - (error: Error) => { - alertMsg(error.message) + checkValid() + const file = fileUploaders.value[0]?.file + if (props.onChange) { + props.onChange(file) } - ) + if (file) { + ctx.emit('fileSelect', file) + } + if (autoUpload.value) { + fileUpload() + } + }) + .catch((error: Error) => { + alertMsg(error.message) + }) } const handleClick = () => { @@ -154,11 +146,17 @@ export default defineComponent({ const files = getFiles() deleteFile(files[0]) } + // 删除已上传文件 + const deleteUploadedFile = (file: File) => { + const newUploadedFiles = uploadedFiles.value.filter((uploadedFile) => { + return uploadedFile.name !== file.name + }) + ctx.emit('deleteUploadedFileEvent', file) + ctx.emit('update:uploadedFiles', newUploadedFiles) + } const onFileDrop = (files: File[]) => { isDropOVer.value = false - _dealFiles( - triggerDropFiles(fileOptions.value, uploadOptions.value, files) - ) + _dealFiles(triggerDropFiles(files)) ctx.emit('fileDrop', files[0]) } const onFileOver = (event: boolean) => { @@ -180,6 +178,8 @@ export default defineComponent({ onFileOver, isDropOVer, showTip, + uploadedFiles, + deleteUploadedFile, } }, render() { @@ -199,91 +199,87 @@ export default defineComponent({ isDropOVer, disabled, showTip, + uploadedFiles, + deleteUploadedFile, } = this - return ( - <> +
-
-
- {!filename && ( -
- {placeholderText} -
- )} - {!!filename && ( -
- {this.$slots.default()}
+ ) : ( +
+
+ {!filename && ( +
+ {placeholderText} +
+ )} + {!!filename && ( +
- {filename} - - onDeleteFile(event)} - /> - {fileUploaders[0]?.status === UploadStatus.uploading && ( -
- -
- )} - {fileUploaders[0].status === UploadStatus.failed && ( - - )} - {fileUploaders[0].status === UploadStatus.uploaded && ( - - )} -
- )} + + {filename} + + onDeleteFile(event)} + /> + {fileUploaders[0]?.status === UploadStatus.uploading && ( +
+ +
+ )} + {fileUploaders[0].status === UploadStatus.failed && ( + + )} + {fileUploaders[0].status === UploadStatus.uploaded && ( + + )} +
+ )} +
+ + +
- - - - - -
- + )} {!autoUpload && !withoutBtn && ( )} - +
+ {this.$slots.preloadFiles?.({ + fileUploaders, + deleteFile: onDeleteFile, + })} +
+
+ {this.$slots.uploadedFiles?.({ + uploadedFiles, + deleteFile: deleteUploadedFile, + })} +
+
) }, }) diff --git a/devui/upload/src/upload-types.ts b/devui/upload/src/upload-types.ts index 8820d2387f7a0df48461a8bb971f2a076a6e5932..cc5ad91580ad011c1da666b74eb0bd755f5cd25b 100644 --- a/devui/upload/src/upload-types.ts +++ b/devui/upload/src/upload-types.ts @@ -1,6 +1,4 @@ import type { PropType, ExtractPropTypes } from 'vue' -import { Observable } from 'rxjs' -import { FileUploader } from './file-uploader' export class IUploadOptions { // 上传接口地址 uri: string @@ -45,9 +43,7 @@ export enum UploadStatus { type DynamicUploadOptionsFn = (files, uploadOptions) => IUploadOptions type ChangeFn = (_: any) => void -type BeforeUploadFn = ( - file: File -) => boolean | Promise | Observable +type BeforeUploadFn = (file: File) => boolean | Promise export const uploadProps = { uploadOptions: { type: Object as PropType, @@ -69,22 +65,14 @@ export const uploadProps = { type: String, default: '选择文件', }, - // TODO - preloadFilesRef: { - type: Object, - }, uploadText: { type: String, default: '上传', }, uploadedFiles: { - type: Array, + type: Array as PropType, default: () => [], }, - // TODO - uploadedFilesRef: { - type: Object, - }, withoutBtn: { type: Boolean, default: false, @@ -135,33 +123,7 @@ export const uploadProps = { default: undefined, }, } as const -export const singleUploadViewProps = { - uploadOptions: { - type: Object as PropType, - }, - // TODO - preloadFilesRef: { - type: Object, - }, - uploadedFiles: { - type: Array, - }, - // TODO - uploadedFilesRef: { - type: Object, - }, - filePath: { - type: String, - required: true, - }, - dynamicUploadOptionsFn: { - type: Function as PropType, - }, -} export type UploadProps = ExtractPropTypes -export type singleUploadViewProps = ExtractPropTypes< - typeof singleUploadViewProps -> export const multiUploadProps = { uploadOptions: { @@ -174,7 +136,6 @@ export const multiUploadProps = { }, filePath: { type: String, - required: true, }, autoUpload: { type: Boolean, @@ -196,14 +157,6 @@ export const multiUploadProps = { type: Boolean, default: false, }, - // TODO - uploadedFilesRef: { - type: Object, - }, - // TODO - preloadFilesRef: { - type: Object, - }, placeholderText: { type: String, default: '选择文件', @@ -221,9 +174,7 @@ export const multiUploadProps = { default: false, }, beforeUpload: { - type: Function as PropType< - (files: any) => boolean | Promise | Observable - >, + type: Function as PropType<(files: any) => boolean | Promise>, }, fileDrop: { type: Function as PropType<(v: any) => void>, diff --git a/devui/upload/src/upload.scss b/devui/upload/src/upload.scss index edabc30117fab9d0a1f5d9544b9737fcdfadd479..287179cd863a6343b2f838f9c0e30067b8a88172 100644 --- a/devui/upload/src/upload.scss +++ b/devui/upload/src/upload.scss @@ -50,14 +50,10 @@ cursor: pointer; height: 100%; position: relative; - display: inline-block; - - svg { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - } + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; } .devui-input-group .devui-form-control { @@ -176,10 +172,6 @@ color: $devui-disabled-text; } -svg.svg-icon-dot > path { - fill: $devui-icon-text; -} - .devui-form-control { outline: none; } diff --git a/devui/upload/src/use-select-files.ts b/devui/upload/src/use-select-files.ts index cce6f208165cd676353f4dc2db19c24a3ec5607e..75caa61b0edeeb61d1718c44fa3bef0f777b4deb 100644 --- a/devui/upload/src/use-select-files.ts +++ b/devui/upload/src/use-select-files.ts @@ -1,6 +1,4 @@ import { ref } from 'vue' -import { from, Observable } from 'rxjs' -import { mergeMap } from 'rxjs/operators' import { IFileOptions, IUploadOptions } from './upload-types' import { getNotAllowedFileTypeMsg, @@ -128,18 +126,10 @@ export const useSelectFiles = () => { const triggerSelectFiles = (fileOptions: IFileOptions) => { const { multiple, accept, webkitdirectory } = fileOptions - return from(selectFiles({ multiple, accept, webkitdirectory })).pipe( - mergeMap((file) => file) - ) + return selectFiles({ multiple, accept, webkitdirectory }) } - const triggerDropFiles = ( - fileOptions: IFileOptions, - uploadOptions: IUploadOptions, - files: any - ) => { - return new Observable((observer) => observer.next(files)).pipe( - mergeMap((file) => file) - ) + const triggerDropFiles = (files: File[]) => { + return Promise.resolve(files) } const checkAllFilesSize = (fileSize, maximumSize) => { if (beyondMaximalSize(fileSize, maximumSize)) { diff --git a/devui/upload/src/use-upload.ts b/devui/upload/src/use-upload.ts index 48427ba15c20b4f74e11e30a767d093b8816bb49..72aa7a48d655743b091c0ad1445955aec4dddc83 100644 --- a/devui/upload/src/use-upload.ts +++ b/devui/upload/src/use-upload.ts @@ -1,6 +1,4 @@ import { ref } from 'vue' -import { from, merge } from 'rxjs' -import { toArray } from 'rxjs/operators' import { FileUploader } from './file-uploader' import { UploadStatus } from './upload-types' @@ -64,11 +62,20 @@ export const useUpload = () => { return finalUploads } - const upload = (oneFile?) => { + const upload = async ( + oneFile? + ): Promise< + | never + | { + file: File + response: any + }[] + > => { let uploads: any[] = [] if (oneFile) { oneFile.percentage = 0 - uploads.push(from(oneFile.send())) + const uploadedFile = await oneFile.send() + uploads.push(uploadedFile) } else { const preFiles = fileUploaders.value.filter( (fileUploader) => fileUploader.status === UploadStatus.preLoad @@ -77,28 +84,26 @@ export const useUpload = () => { (fileUploader) => fileUploader.status === UploadStatus.failed ) const uploadFiles = preFiles.length > 0 ? preFiles : failedFiles - uploads = uploadFiles.map((fileUploader) => { - fileUploader.percentage = 0 - return from(fileUploader.send()) - }) + uploads = await Promise.all( + uploadFiles.map(async (fileUploader) => { + fileUploader.percentage = 0 + const uploadedFile = await fileUploader.send() + return uploadedFile + }) + ) } if (uploads.length > 0) { - return merge< - { - file: File - response: any - }[] - >(...uploads).pipe(toArray()) + return Promise.resolve(uploads) } - return from(Promise.reject('no files')) + return Promise.reject('no files') } const _oneTimeUpload = () => { const uploads = fileUploaders.value.filter( (fileUploader) => fileUploader.status !== UploadStatus.uploaded ) - return from(dealOneTimeUploadFiles(uploads)) + return dealOneTimeUploadFiles(uploads) } const deleteFile = (file) => { diff --git a/sites/components/upload/index.md b/sites/components/upload/index.md index 30ac446efd382b7d8f8b379b726f0028e4409601..6300ab68fb1b8789e32e91a372c6fd051dbe73cb 100644 --- a/sites/components/upload/index.md +++ b/sites/components/upload/index.md @@ -19,7 +19,7 @@ +``` + +::: + +自定义默认 slot,初始显示已上传文件。 + +:::demo + +```vue + + + +``` + +::: + ### API d-single-upload 参数 -| **参数** | **类型** | **默认** | 说明 | **跳转 Demo** | -| ---------------------- | ---------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------- | --------------------- | -| fileOptions | [IFileOptions](#ifileoptions) | -- | 必选,待上传文件配置 | [基本用法](#基本用法) | -| filePath | `string` | -- | 必选,文件路径 | [基本用法](#基本用法) | -| uploadOptions | [IUploadOptions](#iuploadoptions) | \-- | 必选,上传配置 | [基本用法](#基本用法) | -| autoUpload | `boolean` | false | 可选,是否自动上传 | [基本用法](#基本用法) | -| placeholderText | `string` | '选择文件' | 可选,上传输入框中的 Placeholder 文字 | [基本用法](#基本用法) | -| uploadText | `string` | '上传' | 可选,上传按钮文字 | [基本用法](#基本用法) | -| uploadedFiles | `Array` | [] | 可选,获取已上传的文件列表 | [基本用法](#基本用法) | -| withoutBtn | `boolean` | false | 可选,是否舍弃按钮 | [基本用法](#基本用法) | -| enableDrop | `boolean` | false | 可选,是否支持拖拽 | [基本用法](#基本用法) | -| beforeUpload | `boolean Promise Observable` | \-- | 可选,上传前的回调,通过返回`true` or `false` ,控制文件是否上传,参数为文件信息及上传配置 | [基本用法](#基本用法) | -| dynamicUploadOptionsFn | [IUploadOptions](#iuploadoptions) | \-- | 为文件动态设置自定义的上传参数, 参数为当前选中文件及`uploadOptions`的值 | [基本用法](#基本用法) | -| disabled | `boolean` | false | 可选,是否禁用上传组件 | [基本用法](#基本用法) | -| showTip | `boolean` | false | 可选,是否显示上传提示信息 | [自动上传](#自动上传) | +| **参数** | **类型** | **默认** | 说明 | **跳转 Demo** | +| ---------------------- | --------------------------------- | ---------- | ---------------------------------------------------------------------------------------- | --------------------- | +| fileOptions | [IFileOptions](#ifileoptions) | -- | 必选,待上传文件配置 | [基本用法](#基本用法) | +| filePath | `string` | -- | 文件路径 | [基本用法](#基本用法) | +| uploadOptions | [IUploadOptions](#iuploadoptions) | \-- | 必选,上传配置 | [基本用法](#基本用法) | +| autoUpload | `boolean` | false | 可选,是否自动上传 | [基本用法](#基本用法) | +| placeholderText | `string` | '选择文件' | 可选,上传输入框中的 Placeholder 文字 | [基本用法](#基本用法) | +| uploadText | `string` | '上传' | 可选,上传按钮文字 | [基本用法](#基本用法) | +| uploadedFiles | `Array` | [] | 可选,获取已上传的文件列表 | [基本用法](#基本用法) | +| withoutBtn | `boolean` | false | 可选,是否舍弃按钮 | [基本用法](#基本用法) | +| enableDrop | `boolean` | false | 可选,是否支持拖拽 | [基本用法](#基本用法) | +| beforeUpload | `boolean Promise ` | \-- | 可选,上传前的回调,通过返回`true` or `false` ,控制文件是否上传,参数为文件信息及上传配置 | [基本用法](#基本用法) | +| dynamicUploadOptionsFn | [IUploadOptions](#iuploadoptions) | \-- | 为文件动态设置自定义的上传参数, 参数为当前选中文件及`uploadOptions`的值 | [基本用法](#基本用法) | +| disabled | `boolean` | false | 可选,是否禁用上传组件 | [基本用法](#基本用法) | +| showTip | `boolean` | false | 可选,是否显示上传提示信息 | [自动上传](#自动上传) | d-single-upload 事件 @@ -885,22 +1217,22 @@ d-single-upload 事件 d-multiple-upload 参数 -| **参数** | **类型** | **默认** | 说明 | **跳转 Demo** | -| ---------------------- | ---------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------- | ------------------------- | -| fileOptions | [IFileOptions](#ifileoptions) | -- | 必选,待上传文件配置 | [多文件上传](#多文件上传) | -| filePath | `string` | -- | 必选,文件路径 | [多文件上传](#多文件上传) | -| uploadOptions | [IUploadOptions](#iuploadoptions) | \-- | 必选,上传配置 | [多文件上传](#多文件上传) | -| autoUpload | `boolean` | false | 可选,是否自动上传 | [自动上传](#自动上传) | -| placeholderText | `string` | '选择多个文件' | 可选,上传输入框中的 Placeholder 文字 | [基本用法](#基本用法) | -| uploadText | `string` | '上传' | 可选,上传按钮文字 | [基本用法](#基本用法) | -| uploadedFiles | `Array` | [] | 可选,获取已上传的文件列表 | [多文件上传](#多文件上传) | -| withoutBtn | `boolean` | false | 可选,是否舍弃按钮 | [自定义](#自定义) | -| enableDrop | `boolean` | false | 可选,是否支持拖拽 | [多文件上传](#多文件上传) | -| beforeUpload | `boolean Promise Observable` | \-- | 可选,上传前的回调,通过返回`true` or `false` ,控制文件是否上传,参数为文件信息及上传配置 | [多文件上传](#多文件上传) | -| dynamicUploadOptionsFn | [IUploadOptions](#iuploadoptions) | \-- | 为文件动态设置自定义的上传参数, 参数为当前选中文件及`uploadOptions`的值 | [多文件上传](#多文件上传) | -| disabled | `boolean` | false | 可选,是否禁用上传组件 | [多文件上传](#多文件上传) | -| showTip | `boolean` | false | 可选,是否显示上传提示信息 | [多文件上传](#多文件上传) | -| setCustomUploadOptions | [IUploadOptions](#iuploadoptions) | -- | 为每个文件设置自定义的上传参数, 参数为当前选中文件及`uploadOptions`的值 | [自定义](#自定义) | +| **参数** | **类型** | **默认** | 说明 | **跳转 Demo** | +| ---------------------- | --------------------------------- | -------------- | ---------------------------------------------------------------------------------------- | ------------------------- | +| fileOptions | [IFileOptions](#ifileoptions) | -- | 必选,待上传文件配置 | [多文件上传](#多文件上传) | +| filePath | `string` | -- | 文件路径 | [多文件上传](#多文件上传) | +| uploadOptions | [IUploadOptions](#iuploadoptions) | \-- | 必选,上传配置 | [多文件上传](#多文件上传) | +| autoUpload | `boolean` | false | 可选,是否自动上传 | [自动上传](#自动上传) | +| placeholderText | `string` | '选择多个文件' | 可选,上传输入框中的 Placeholder 文字 | [基本用法](#基本用法) | +| uploadText | `string` | '上传' | 可选,上传按钮文字 | [基本用法](#基本用法) | +| uploadedFiles | `Array` | [] | 可选,获取已上传的文件列表 | [多文件上传](#多文件上传) | +| withoutBtn | `boolean` | false | 可选,是否舍弃按钮 | [自定义](#自定义) | +| enableDrop | `boolean` | false | 可选,是否支持拖拽 | [多文件上传](#多文件上传) | +| beforeUpload | `boolean Promise` | \-- | 可选,上传前的回调,通过返回`true` or `false` ,控制文件是否上传,参数为文件信息及上传配置 | [多文件上传](#多文件上传) | +| dynamicUploadOptionsFn | [IUploadOptions](#iuploadoptions) | \-- | 为文件动态设置自定义的上传参数, 参数为当前选中文件及`uploadOptions`的值 | [多文件上传](#多文件上传) | +| disabled | `boolean` | false | 可选,是否禁用上传组件 | [多文件上传](#多文件上传) | +| showTip | `boolean` | false | 可选,是否显示上传提示信息 | [多文件上传](#多文件上传) | +| setCustomUploadOptions | [IUploadOptions](#iuploadoptions) | -- | 为每个文件设置自定义的上传参数, 参数为当前选中文件及`uploadOptions`的值 | [自定义](#自定义) | d-multiple-upload 事件