diff --git a/packages/devui-vue/devui/upload/__tests__/upload.spec.ts b/packages/devui-vue/devui/upload/__tests__/upload.spec.ts index 31dcf2239c7aae1b3f7a42a593626cb9b9dedc0f..6960223cf4e20a95a2cba06d3ab797cb07252943 100644 --- a/packages/devui-vue/devui/upload/__tests__/upload.spec.ts +++ b/packages/devui-vue/devui/upload/__tests__/upload.spec.ts @@ -1,76 +1,61 @@ import { mount } from '@vue/test-utils' import { ref, nextTick, reactive } from 'vue' -import DSingleUpload from '../src/single-upload' -import DMultipleUpload from '../src/multiple-upload' +import DUpload from '../src/upload' const getMockFile = (element: Element, files: File[]): void => { Object.defineProperty(element, 'files', { get() { return files - }, + } }) } -describe('single upload', () => { +describe('upload', () => { it('should render correctly', () => { const TestComponent = { components: { - 'd-single-upload': DSingleUpload, + 'd-upload': DUpload }, template: ` - `, setup() { - const fileOptions = reactive({ - accept: '', - multiple: false, - webkitdirectory: false, - }) const uploadOptions = reactive({ - uri: 'http://localhost:4000/files/upload', + uri: 'http://localhost:4000/files/upload' }) const uploadedFiles = ref([]) return { - fileOptions, uploadedFiles, - uploadOptions, + uploadOptions } - }, + } } mount(TestComponent) }) it('should work with `disabled` prop', () => { const TestComponent = { components: { - 'd-single-upload': DSingleUpload, + 'd-upload': DUpload }, template: ` - `, setup() { - const fileOptions = reactive({ - accept: '', - multiple: false, - webkitdirectory: false, - }) const uploadOptions = reactive({ - uri: 'http://localhost:4000/files/upload', + uri: 'http://localhost:4000/files/upload' }) const uploadedFiles = ref([]) return { - fileOptions, uploadedFiles, - uploadOptions, + uploadOptions } - }, + } } const wrapper = mount(TestComponent) expect(wrapper.find('.devui-input-group.disabled').exists()).toBe(true) @@ -80,11 +65,10 @@ describe('single upload', () => { const TestComponent = { components: { - 'd-single-upload': DSingleUpload, + 'd-upload': DUpload }, template: ` - { /> `, setup() { - const fileOptions = reactive({ - accept: '', - multiple: false, - webkitdirectory: false, - }) const uploadOptions = reactive({ - uri: 'http://localhost:4000/files/upload', + uri: 'http://localhost:4000/files/upload' }) const uploadedFiles = ref([]) return { - fileOptions, uploadedFiles, uploadOptions, - beforeUpload, + beforeUpload } - }, + } } const wrapper = mount(TestComponent) const uploadElment = wrapper.find('.devui-input-group') await uploadElment.trigger('click') await nextTick() const input = document.getElementById('d-upload-temp') - const fileList = [new File(['test'], 'file.txt')] + const fileList = [ + new File(['test'], 'file.txt', { + type: 'text/plain', + lastModified: Date.now() + }) + ] getMockFile(input, fileList) const evt = new Event('change') await input.dispatchEvent(evt) expect(beforeUpload).toHaveBeenCalled() expect(wrapper.find('.devui-upload button').exists()).toBe(false) }) - it('should work with `showTip placeholderText uploadText` prop', async () => { + it('should work with `placeholderText uploadText` prop', async () => { const TestComponent = { components: { - 'd-single-upload': DSingleUpload, + 'd-upload': DUpload }, template: ` - `, setup() { - const fileOptions = reactive({ - accept: '', - multiple: false, - webkitdirectory: false, - }) const uploadOptions = reactive({ - uri: 'http://localhost:4000/files/upload', + uri: 'http://localhost:4000/files/upload' }) const uploadedFiles = ref([]) return { - fileOptions, uploadedFiles, - uploadOptions, + uploadOptions } - }, + } } const wrapper = mount(TestComponent) - expect(wrapper.find('.devui-upload-tip').exists()).toBe(true) expect(wrapper.find('.devui-upload-placeholder').text()).toBe('select file') expect(wrapper.find('.devui-upload button').text()).toBe('upload') }) }) - -describe('multi upload', () => { - it('should render correctly', () => { - const TestComponent = { - components: { - 'd-multi-upload': DMultipleUpload, - }, - template: ` -
- -
- `, - setup() { - const fileOptions = reactive({ - accept: '', - multiple: true, - webkitdirectory: false, - }) - const uploadOptions = reactive({ - uri: 'http://localhost:4000/files/upload', - }) - const uploadedFiles = ref([]) - return { - fileOptions, - uploadedFiles, - uploadOptions, - } - }, - } - mount(TestComponent) - }) -}) diff --git a/packages/devui-vue/devui/upload/index.ts b/packages/devui-vue/devui/upload/index.ts index 3eed211d068f49430d7fb5948c635220a1ed3890..227a3ba02ffa9761a94c3e930f2cde021f6b7e93 100644 --- a/packages/devui-vue/devui/upload/index.ts +++ b/packages/devui-vue/devui/upload/index.ts @@ -1,15 +1,13 @@ import type { App } from 'vue' -import Upload from './src/single-upload' -import MultiUpload from './src/multiple-upload' +import Upload from './src/upload' import fileDropDirective from './src/file-drop-directive' Upload.install = function (app: App) { app.directive('file-drop', fileDropDirective) app.component(Upload.name, Upload) - app.component(MultiUpload.name, MultiUpload) } -export { Upload, MultiUpload } +export { Upload } export default { title: 'Upload 上传', diff --git a/packages/devui-vue/devui/upload/src/file-drop-directive.ts b/packages/devui-vue/devui/upload/src/file-drop-directive.ts index e74602f6911ee9ceb94cf7f4269d9acf8a20e72e..86831e711dd60338e45174e104d805378685d429 100644 --- a/packages/devui-vue/devui/upload/src/file-drop-directive.ts +++ b/packages/devui-vue/devui/upload/src/file-drop-directive.ts @@ -8,9 +8,7 @@ interface BindingType { } const getTransfer = (event: any) => { - return event.dataTransfer - ? event.dataTransfer - : event.originalEvent?.dataTransfer + return event.dataTransfer ? event.dataTransfer : event.originalEvent?.dataTransfer } const haveFiles = (types: any) => { @@ -66,7 +64,7 @@ const onDrop = (el: HTMLElement, binding: BindingType) => { if (isSingle) { onFileDrop && onFileDrop([transfer.files[0]]) } else { - onFileDrop && onFileDrop(transfer.files) + onFileDrop && onFileDrop(Array.from(transfer.files)) } }) } @@ -80,7 +78,7 @@ const fileDropDirective = { onDragOver(el, binding) onDragLeave(el, binding) onDrop(el, binding) - }, + } } export default fileDropDirective diff --git a/packages/devui-vue/devui/upload/src/single-upload.tsx b/packages/devui-vue/devui/upload/src/single-upload.tsx index 23c84d49f3acb7b58a4bb3ea54e48a5790d5753b..ff98a5c460cfb6479f69ed6da44887bc8dea6df4 100644 --- a/packages/devui-vue/devui/upload/src/single-upload.tsx +++ b/packages/devui-vue/devui/upload/src/single-upload.tsx @@ -16,7 +16,7 @@ export default defineComponent({ 'successEvent', 'errorEvent', 'deleteUploadedFileEvent', - 'update:uploadedFiles', + 'update:uploadedFiles' ], setup(props: UploadProps, ctx) { const { @@ -30,25 +30,17 @@ export default defineComponent({ beforeUpload, enableDrop, showTip, - uploadedFiles, + uploadedFiles } = toRefs(props) const isDropOVer = ref(false) - const { - getFiles, - fileUploaders, - addFile, - getFullFiles, - deleteFile, - upload, - removeFiles, - } = useUpload() - const { triggerSelectFiles, _validateFiles, triggerDropFiles } = - useSelectFiles() + const { getFiles, fileUploaders, addFile, getFullFiles, deleteFile, upload, removeFiles } = + useUpload() + const { triggerSelectFiles, _validateFiles, triggerDropFiles } = useSelectFiles() const filename = computed(() => (getFiles()[0] || {}).name || '') const alertMsg = (errorMsg: string) => { ToastService.open({ - value: [{ severity: 'warn', content: errorMsg }], + value: [{ severity: 'warn', content: errorMsg }] }) } @@ -133,8 +125,7 @@ export default defineComponent({ const handleClick = () => { if ( disabled.value || - (fileUploaders.value[0] && - fileUploaders.value[0]?.status === UploadStatus.uploading) + (fileUploaders.value[0] && fileUploaders.value[0]?.status === UploadStatus.uploading) ) { return } @@ -179,7 +170,7 @@ export default defineComponent({ isDropOVer, showTip, uploadedFiles, - deleteUploadedFile, + deleteUploadedFile } }, render() { @@ -200,12 +191,12 @@ export default defineComponent({ disabled, showTip, uploadedFiles, - deleteUploadedFile, + deleteUploadedFile } = this return (
@@ -214,35 +205,29 @@ export default defineComponent({ ) : (
-
+
{!filename && ( -
- {placeholderText} -
+
{placeholderText}
)} {!!filename && (
{filename} onDeleteFile(event)} /> {fileUploaders[0]?.status === UploadStatus.uploading && ( -
+
)} {fileUploaders[0].status === UploadStatus.failed && ( - + )} {fileUploaders[0].status === UploadStatus.uploaded && ( - + )}
)}
- - + +
)} {!autoUpload && !withoutBtn && ( - {(!fileUploaders[0] || !fileUploaders[0]?.status) && ( - {uploadText} - )} - {fileUploaders[0]?.status === UploadStatus.uploading && ( - 上传中... - )} - {fileUploaders[0]?.status === UploadStatus.uploaded && ( - 已上传 - )} - {fileUploaders[0]?.status === UploadStatus.failed && ( - 上传失败 - )} + {(!fileUploaders[0] || !fileUploaders[0]?.status) && {uploadText}} + {fileUploaders[0]?.status === UploadStatus.uploading && 上传中...} + {fileUploaders[0]?.status === UploadStatus.uploaded && 已上传} + {fileUploaders[0]?.status === UploadStatus.failed && 上传失败} )}
{showTip && ( -
+
{fileUploaders[0]?.status === UploadStatus.uploading && ( - {i18nText.uploading} + {i18nText.uploading} )} {fileUploaders[0]?.status === UploadStatus.uploaded && ( -
- - - {i18nText.uploadSuccess} - +
+ + {i18nText.uploadSuccess}
)} {fileUploaders[0]?.status === UploadStatus.failed && ( -
- - - {i18nText.uploadFailed} +
+ + + {i18nText.uploadFailed} {i18nText.reUpload}
@@ -331,16 +304,16 @@ export default defineComponent({
{this.$slots.preloadFiles?.({ fileUploaders, - deleteFile: onDeleteFile, + deleteFile: onDeleteFile })}
{this.$slots.uploadedFiles?.({ uploadedFiles, - deleteFile: deleteUploadedFile, + deleteFile: deleteUploadedFile })}
) - }, + } }) diff --git a/packages/devui-vue/devui/upload/src/upload-types.ts b/packages/devui-vue/devui/upload/src/upload-types.ts index 1567766aa35c53c34003545ebc17f4299dac26e8..d9e564926da0cbbe0b40b0336de28d5215a19531 100644 --- a/packages/devui-vue/devui/upload/src/upload-types.ts +++ b/packages/devui-vue/devui/upload/src/upload-types.ts @@ -1,4 +1,5 @@ import type { PropType, ExtractPropTypes } from 'vue' +import { FileUploader } from './file-uploader' export class IUploadOptions { // 上传接口地址 uri: string @@ -30,7 +31,7 @@ export class IUploadOptions { export class IFileOptions { accept?: string - multiple: boolean + multiple?: boolean webkitdirectory: boolean } @@ -38,165 +39,95 @@ export enum UploadStatus { preLoad = 0, uploading, uploaded, - failed, + failed } type DynamicUploadOptionsFn = (files, uploadOptions) => IUploadOptions type ChangeFn = (_: any) => void -type BeforeUploadFn = (file: File) => boolean | Promise +type BeforeUploadFn = (file: FileUploader) => boolean | Promise export const uploadProps = { + // 规定能够通过文件上传进行提交的文件类型,例如 accept: '.xls,.xlsx,.pages,.mp3,.png' + accept: { + type: String + }, + // 是否允许用户选择文件目录,而不是文件 + webkitdirectory: { + type: Boolean, + default: false + }, uploadOptions: { type: Object as PropType, - required: true, + required: true }, - fileOptions: { - type: Object as PropType, - required: true, + multiple: { + type: Boolean, + default: false }, autoUpload: { type: Boolean, - default: false, + default: false }, placeholderText: { type: String, - default: '选择文件', + default: '选择文件' }, uploadText: { type: String, - default: '上传', + default: '上传' }, uploadedFiles: { type: Array as PropType, - default: () => [], + default: () => [] }, withoutBtn: { type: Boolean, - default: false, + default: false }, enableDrop: { type: Boolean, - default: false, + default: false }, beforeUpload: { - type: Function as PropType, + type: Function as PropType }, + /** @deprecated */ dynamicUploadOptionsFn: { - type: Function as PropType, + type: Function as PropType }, disabled: { type: Boolean, - default: false, - }, - showTip: { - type: Boolean, - default: false, + default: false }, onChange: { - type: Function as PropType, + type: Function as PropType }, fileDrop: { type: Function as PropType<(v: any) => void>, - default: undefined, + default: undefined }, fileOver: { type: Function as PropType<(v: boolean) => void>, - default: undefined, + default: undefined }, fileSelect: { type: Function as PropType<(v: File) => void>, - default: undefined, - }, - errorEvent: { - type: Function as PropType<(v: { file: File; response: any; }) => void>, - default: undefined, + default: undefined }, - successEvent: { - type: Function as PropType<(v: { file: File; response: any; }[]) => void>, - default: undefined, - }, - deleteUploadedFileEvent: { + deleteUploadedFile: { type: Function as PropType<(v: string) => void>, - default: undefined, - }, -} as const -export type UploadProps = ExtractPropTypes - -export const multiUploadProps = { - uploadOptions: { - type: Object as PropType, - required: true, + default: undefined }, - fileOptions: { - type: Object as PropType, - required: true, - }, - autoUpload: { - type: Boolean, - default: false, - }, - withoutBtn: { - type: Boolean, - default: false, - }, - showTip: { - type: Boolean, - default: false, - }, - uploadedFiles: { - type: Array as PropType, - default: () => [], - }, - enableDrop: { - type: Boolean, - default: false, - }, - placeholderText: { - type: String, - default: '选择文件', - }, - uploadText: { - type: String, - default: '上传', - }, - oneTimeUpload: { - type: Boolean, - default: false, - }, - disabled: { - type: Boolean, - default: false, - }, - beforeUpload: { - type: Function as PropType<(files: any) => boolean | Promise>, - }, - fileDrop: { - type: Function as PropType<(v: any) => void>, - default: undefined, - }, - fileOver: { - type: Function as PropType<(v: boolean) => void>, - default: undefined, - }, - fileSelect: { - type: Function as PropType<(v: File) => void>, - default: undefined, - }, - errorEvent: { + 'on-error': { type: Function as PropType<(v: { file: File; response: any; }) => void>, - default: undefined, + default: undefined }, - successEvent: { + 'on-success': { type: Function as PropType<(v: { file: File; response: any; }[]) => void>, - default: undefined, - }, - deleteUploadedFileEvent: { - type: Function as PropType<(v: string) => void>, - default: undefined, + default: undefined }, - setCustomUploadOptions: { - type: Function as PropType< - (files: File[], uploadOptions: IUploadOptions) => IUploadOptions - >, - default: undefined, - }, -} + oneTimeUpload: { + type: Boolean, + default: false + } +} as const +export type UploadProps = ExtractPropTypes diff --git a/packages/devui-vue/devui/upload/src/multiple-upload.tsx b/packages/devui-vue/devui/upload/src/upload.tsx similarity index 76% rename from packages/devui-vue/devui/upload/src/multiple-upload.tsx rename to packages/devui-vue/devui/upload/src/upload.tsx index 0928fe4106b23878bb278236f0a9062e1de07173..8678147cf3bcfc23fd646598cca65756904adf7d 100644 --- a/packages/devui-vue/devui/upload/src/multiple-upload.tsx +++ b/packages/devui-vue/devui/upload/src/upload.tsx @@ -1,34 +1,24 @@ import { defineComponent, toRefs, ref } from 'vue' import { ToastService } from '../../toast' -import { UploadStatus, multiUploadProps } from './upload-types' +import { UploadStatus, UploadProps, uploadProps } from './upload-types' import { useSelectFiles } from './use-select-files' import { useUpload } from './use-upload' import { getFailedFilesCount, getSelectedFilesCount, getUploadingFilesCount, - i18nText, - getExistSameNameFilesMsg, + getExistSameNameFilesMsg } from './i18n-upload' import { FileUploader } from './file-uploader' import './upload.scss' export default defineComponent({ - name: 'DMultipleUpload', - props: multiUploadProps, - emits: [ - 'fileDrop', - 'fileOver', - 'fileSelect', - 'successEvent', - 'errorEvent', - 'deleteUploadedFileEvent', - 'update:uploadedFiles', - ], - setup(props, ctx) { + name: 'DUpload', + props: uploadProps, + emits: ['fileDrop', 'fileOver', 'fileSelect', 'deleteUploadedFile', 'update:uploadedFiles'], + setup(props: UploadProps, ctx) { const { uploadOptions, - fileOptions, placeholderText, autoUpload, withoutBtn, @@ -37,17 +27,14 @@ export default defineComponent({ beforeUpload, enableDrop, oneTimeUpload, - showTip, uploadedFiles, + multiple, + accept, + webkitdirectory } = toRefs(props) + const { triggerSelectFiles, _validateFiles, triggerDropFiles, checkAllFilesSize } = + useSelectFiles() const { - triggerSelectFiles, - _validateFiles, - triggerDropFiles, - checkAllFilesSize, - } = useSelectFiles() - const { - getFiles, fileUploaders, addFile, getFullFiles, @@ -56,13 +43,13 @@ export default defineComponent({ resetSameNameFiles, removeFiles, _oneTimeUpload, - getSameNameFiles, + getSameNameFiles } = useUpload() const isDropOVer = ref(false) const uploadTips = ref('') const alertMsg = (errorMsg: string) => { ToastService.open({ - value: [{ severity: 'warn', content: errorMsg }], + value: [{ severity: 'warn', content: errorMsg }] }) } const checkValid = () => { @@ -73,7 +60,7 @@ export default defineComponent({ const checkResult = _validateFiles( fileUploader.file, - fileOptions.value.accept, + accept.value, fileUploader.uploadOptions ) if (checkResult && checkResult.checkError) { @@ -84,10 +71,7 @@ export default defineComponent({ }) if (oneTimeUpload.value) { - const checkResult = checkAllFilesSize( - totalFileSize, - uploadOptions.value.maximumSize - ) + const checkResult = checkAllFilesSize(totalFileSize, uploadOptions.value.maximumSize) if (checkResult && checkResult.checkError) { removeFiles() alertMsg(checkResult.errorMsg) @@ -100,6 +84,10 @@ export default defineComponent({ promise .then((files) => { files.forEach((file) => { + // 单文件上传前先清空数组 + if (!multiple.value) { + removeFiles() + } addFile(file, uploadOptions.value) // debounceTime(100) }) @@ -109,13 +97,11 @@ export default defineComponent({ alertMsg(getExistSameNameFilesMsg(sameNameFiles)) } const selectedFiles = fileUploaders.value - .filter( - (fileUploader) => fileUploader.status === UploadStatus.preLoad - ) + .filter((fileUploader) => fileUploader.status === UploadStatus.preLoad) .map((fileUploader) => fileUploader.file) ctx.emit('fileSelect', selectedFiles) if (autoUpload.value) { - upload() + fileUpload() } }) .catch((error: Error) => { @@ -127,7 +113,13 @@ export default defineComponent({ if (disabled.value) { return } - _dealFiles(triggerSelectFiles(fileOptions.value)) + _dealFiles( + triggerSelectFiles({ + accept: accept.value, + multiple: multiple.value, + webkitdirectory: webkitdirectory.value + }) + ) } const onFileDrop = (files: File[]) => { @@ -139,18 +131,21 @@ export default defineComponent({ isDropOVer.value = event ctx.emit('fileOver', event) } - const onDeleteFile = (event: Event, file: File) => { - event.stopPropagation() - deleteFile(file) - } // 删除已上传文件 const deleteUploadedFile = (file: File) => { const newUploadedFiles = uploadedFiles.value.filter((uploadedFile) => { return uploadedFile.name !== file.name }) - ctx.emit('deleteUploadedFileEvent', file) + ctx.emit('deleteUploadedFile', file) ctx.emit('update:uploadedFiles', newUploadedFiles) } + const onDeleteFile = (event: Event, file: File, status: UploadStatus) => { + event.stopPropagation() + if (status === UploadStatus.uploaded) { + deleteUploadedFile(file) + } + deleteFile(file) + } const canUpload = () => { let uploadResult = Promise.resolve(true) if (beforeUpload.value) { @@ -174,19 +169,17 @@ export default defineComponent({ removeFiles() return } - const uploadObservable = oneTimeUpload.value - ? _oneTimeUpload() - : upload(fileUploader) + const uploadObservable = oneTimeUpload.value ? _oneTimeUpload() : upload(fileUploader) uploadObservable .then((results: Array<{ file: File; response: any; }>) => { - ctx.emit('successEvent', results) + props['on-success'] && props['on-success'](results) const newFiles = results.map((result) => result.file) const newUploadedFiles = [...newFiles, ...uploadedFiles.value] ctx.emit('update:uploadedFiles', newUploadedFiles) }) .catch((error) => { - ctx.emit('errorEvent', error) + props['on-error'] && props['on-error'](error) }) }) } @@ -236,7 +229,6 @@ export default defineComponent({ return { uploadOptions, - fileOptions, placeholderText, autoUpload, withoutBtn, @@ -251,11 +243,11 @@ export default defineComponent({ fileUploaders, onDeleteFile, fileUpload, - showTip, getStatus, uploadTips, cancelUpload, deleteUploadedFile, + multiple } }, render() { @@ -265,7 +257,6 @@ export default defineComponent({ withoutBtn, uploadText, disabled, - beforeUpload, enableDrop, isDropOVer, onFileDrop, @@ -274,52 +265,43 @@ export default defineComponent({ fileUploaders, onDeleteFile, fileUpload, - showTip, - getStatus, - uploadTips, - cancelUpload, uploadedFiles, deleteUploadedFile, + multiple } = this + return ( - <> +
{this.$slots.default?.() ? (
{this.$slots.default()}
) : ( -
+
{fileUploaders.length === 0 && ( -
- {placeholderText} -
+
{placeholderText}
)} {fileUploaders.length > 0 && ( -
    +
      {fileUploaders.map((fileUploader, index) => (
    • {fileUploader.file.name} - onDeleteFile(event, fileUploader.file) + onDeleteFile(event, fileUploader.file, fileUploader.status) } /> {fileUploader.status === UploadStatus.uploading && ( -
      +
      )} {fileUploader.status === UploadStatus.failed && ( - + )} {fileUploader.status === UploadStatus.uploaded && ( - + )}
    • ))}
    )} - - + +
)} {!autoUpload && !withoutBtn && ( @@ -375,16 +357,16 @@ export default defineComponent({
{this.$slots.preloadFiles?.({ fileUploaders, - deleteFile: onDeleteFile, + deleteFile: onDeleteFile })}
{this.$slots.uploadedFiles?.({ uploadedFiles, - deleteFile: deleteUploadedFile, + deleteFile: deleteUploadedFile })}
- +
) - }, + } }) diff --git a/packages/devui-vue/devui/upload/src/use-select-files.ts b/packages/devui-vue/devui/upload/src/use-select-files.ts index 75caa61b0edeeb61d1718c44fa3bef0f777b4deb..83e5bd353e17f6d75cf3cb11fa8f8d2a15eabe0f 100644 --- a/packages/devui-vue/devui/upload/src/use-select-files.ts +++ b/packages/devui-vue/devui/upload/src/use-select-files.ts @@ -1,9 +1,9 @@ import { ref } from 'vue' -import { IFileOptions, IUploadOptions } from './upload-types' +import { IFileOptions } from './upload-types' import { getNotAllowedFileTypeMsg, getBeyondMaximalFileSizeMsg, - getAllFilesBeyondMaximalFileSizeMsg, + getAllFilesBeyondMaximalFileSizeMsg } from './i18n-upload' export const useSelectFiles = () => { @@ -29,11 +29,7 @@ export const useSelectFiles = () => { ) input.dispatchEvent(evt) } - const selectFiles = ({ - multiple, - accept, - webkitdirectory, - }: IFileOptions): Promise => { + const selectFiles = ({ multiple, accept, webkitdirectory }: IFileOptions): Promise => { return new Promise((resolve) => { const tempNode = document.getElementById('d-upload-temp') if (tempNode) { @@ -59,9 +55,7 @@ export const useSelectFiles = () => { } input.addEventListener('change', (event) => { - resolve( - Array.prototype.slice.call((event.target as HTMLInputElement).files) - ) + resolve(Array.prototype.slice.call((event.target as HTMLInputElement).files)) }) document.body.appendChild(input) // Fix compatibility issue with Internet Explorer 11 simulateClickEvent(input) @@ -106,19 +100,13 @@ export const useSelectFiles = () => { if (!isAllowedFileType(accept, file)) { return { checkError: true, - errorMsg: getNotAllowedFileTypeMsg((file).name, accept), + errorMsg: getNotAllowedFileTypeMsg((file).name, accept) } } - if ( - uploadOptions && - beyondMaximalSize((file).size, uploadOptions.maximumSize) - ) { + if (uploadOptions && beyondMaximalSize((file).size, uploadOptions.maximumSize)) { return { checkError: true, - errorMsg: getBeyondMaximalFileSizeMsg( - (file).name, - uploadOptions.maximumSize - ), + errorMsg: getBeyondMaximalFileSizeMsg((file).name, uploadOptions.maximumSize) } } return { checkError: false, errorMsg: undefined } @@ -133,8 +121,7 @@ export const useSelectFiles = () => { } const checkAllFilesSize = (fileSize, maximumSize) => { if (beyondMaximalSize(fileSize, maximumSize)) { - BEYOND_MAXIMAL_FILE_SIZE_MSG.value = - getAllFilesBeyondMaximalFileSizeMsg(maximumSize) + BEYOND_MAXIMAL_FILE_SIZE_MSG.value = getAllFilesBeyondMaximalFileSizeMsg(maximumSize) return { checkError: true, errorMsg: BEYOND_MAXIMAL_FILE_SIZE_MSG.value } } } @@ -142,6 +129,6 @@ export const useSelectFiles = () => { triggerSelectFiles, _validateFiles, triggerDropFiles, - checkAllFilesSize, + checkAllFilesSize } } diff --git a/packages/devui-vue/docs/components/upload/index.md b/packages/devui-vue/docs/components/upload/index.md index 425c5b82195bad1cd91f6801a141ca36243d0c9e..347f983b2ff07fb9107c22d95fbd1c8339b329fd 100644 --- a/packages/devui-vue/docs/components/upload/index.md +++ b/packages/devui-vue/docs/components/upload/index.md @@ -8,7 +8,7 @@ ### 基本用法 -单文件上传、拖动文件上传、禁止上传。 +单文件上传、多文件上传、拖动文件上传、禁止上传。

Basic Usage

@@ -16,11 +16,7 @@ ```vue ``` ::: -

Dragdrop

+

Multiple Files

:::demo ```vue ``` ::: -

Disabled

+

Dragdrop

:::demo ```vue -``` - -::: - -### 多文件上传 - -多文件上传,支持拖动文件上传、禁止上传。 - -

Basic Usage

- -:::demo - -```vue - - -``` - -::: - -

Upload Directory

- -:::demo - -```vue - - -``` - -::: - -

Dragdrop

- -:::demo - -```vue - - ``` @@ -430,14 +166,13 @@ export default { ```vue @@ -448,11 +183,6 @@ export default { setup() { const additionalParameter = { name: 'tom', age: 11 } const uploadedFiles = ref([]) - const fileOptions = reactive({ - accept: '', - multiple: false, - webkitdirectory: false, - }) const uploadOptions = reactive({ uri: '/upload', headers: {}, @@ -461,7 +191,7 @@ export default { method: 'POST', fileFieldName: 'dFile', withCredentials: true, - responseType: 'json', + responseType: 'json' }) const beforeUpload = (file) => { console.log(file) @@ -474,14 +204,13 @@ export default { console.log(error) } return { - fileOptions, uploadedFiles, uploadOptions, beforeUpload, onSuccess, - onError, + onError } - }, + } } ``` @@ -496,17 +225,19 @@ export default { ```vue -``` - -::: - -### 自定义 - -自定义上传按钮,通过 slot preloadFiles 设置已选择文件列表模板,通过 slot uploadedFiles 设置已上传文件列表模版。 - -:::demo - -```vue - - - ``` ::: @@ -783,13 +293,12 @@ export default { ```vue @@ -800,11 +309,6 @@ export default { setup() { const additionalParameter = { name: 'tom', age: 11 } const uploadedFiles = ref([]) - const fileOptions = reactive({ - accept: '', - multiple: false, - webkitdirectory: false, - }) const uploadOptions = reactive({ uri: 'http://localhost:4000/files/upload', headers: {}, @@ -812,7 +316,7 @@ export default { maximumSize: 0.5, method: 'POST', fileFieldName: 'file', - responseType: 'json', + responseType: 'json' }) const beforeUpload = (files) => { if (!files || !files.length) { @@ -829,14 +333,13 @@ export default { console.log(error) } return { - fileOptions, uploadedFiles, uploadOptions, beforeUpload, onSuccess, - onError, + onError } - }, + } } ``` @@ -850,44 +353,29 @@ export default { ```vue ``` @@ -999,18 +471,19 @@ export default { ```vue