feat: 上传list-type

This commit is contained in:
dap 2025-03-30 18:23:37 +08:00
parent a302fdf119
commit 755a30583f
4 changed files with 96 additions and 5 deletions

View File

@ -3,6 +3,8 @@
去除使用`file-type`库进行文件类型检测 在Safari无法使用 去除使用`file-type`库进行文件类型检测 在Safari无法使用
--> -->
<script setup lang="ts"> <script setup lang="ts">
import type { UploadListType } from 'ant-design-vue/es/upload/interface';
import type { BaseUploadProps, UploadEmits } from './props'; import type { BaseUploadProps, UploadEmits } from './props';
import { computed } from 'vue'; import { computed } from 'vue';
@ -17,7 +19,14 @@ import { uploadApi } from '#/api';
import { defaultFileAcceptExts, defaultFilePreview } from './helper'; import { defaultFileAcceptExts, defaultFilePreview } from './helper';
import { useUpload } from './hook'; import { useUpload } from './hook';
interface FileUploadProps extends BaseUploadProps {} interface FileUploadProps extends BaseUploadProps {
/**
* 同antdv的listType 但是排除picture-card
* 文件上传不适合用picture-card显示
* @default text
*/
listType?: Exclude<UploadListType, 'picture-card'>;
}
const props = withDefaults(defineProps<FileUploadProps>(), { const props = withDefaults(defineProps<FileUploadProps>(), {
api: () => uploadApi, api: () => uploadApi,
@ -34,6 +43,7 @@ const props = withDefaults(defineProps<FileUploadProps>(), {
enableDragUpload: false, enableDragUpload: false,
directory: false, directory: false,
abortOnUnmounted: true, abortOnUnmounted: true,
listType: 'text',
}); });
const emit = defineEmits<UploadEmits>(); const emit = defineEmits<UploadEmits>();
@ -70,6 +80,7 @@ Upload.Dragger只会影响样式
<CurrentUploadComponent <CurrentUploadComponent
v-model:file-list="innerFileList" v-model:file-list="innerFileList"
:accept="accept" :accept="accept"
:list-type="listType"
:disabled="disabled" :disabled="disabled"
:directory="directory" :directory="directory"
:max-count="maxCount" :max-count="maxCount"

View File

@ -12,7 +12,7 @@ import type { BaseUploadProps, UploadEmits } from './props';
import { $t, I18nT } from '@vben/locales'; import { $t, I18nT } from '@vben/locales';
import { PlusOutlined } from '@ant-design/icons-vue'; import { PlusOutlined, UploadOutlined } from '@ant-design/icons-vue';
import { Image, ImagePreviewGroup, Upload } from 'ant-design-vue'; import { Image, ImagePreviewGroup, Upload } from 'ant-design-vue';
import { isFunction } from 'lodash-es'; import { isFunction } from 'lodash-es';
@ -91,10 +91,19 @@ function currentPreview(file: UploadFile) {
@change="handleChange" @change="handleChange"
@remove="handleRemove" @remove="handleRemove"
> >
<div v-if="innerFileList?.length < maxCount"> <div
v-if="innerFileList?.length < maxCount && listType === 'picture-card'"
>
<PlusOutlined /> <PlusOutlined />
<div class="mt-[8px]">{{ $t('component.upload.upload') }}</div> <div class="mt-[8px]">{{ $t('component.upload.upload') }}</div>
</div> </div>
<a-button
v-if="innerFileList?.length < maxCount && listType !== 'picture-card'"
:disabled="disabled"
>
<UploadOutlined />
{{ $t('component.upload.upload') }}
</a-button>
</Upload> </Upload>
<slot name="helpMessage" v-bind="{ maxCount, disabled, maxSize, accept }"> <slot name="helpMessage" v-bind="{ maxCount, disabled, maxSize, accept }">
<I18nT <I18nT
@ -102,7 +111,10 @@ function currentPreview(file: UploadFile) {
scope="global" scope="global"
keypath="component.upload.uploadHelpMessage" keypath="component.upload.uploadHelpMessage"
tag="div" tag="div"
:class="{ 'upload-text__disabled': disabled }" :class="{
'upload-text__disabled': disabled,
'mt-2': listType !== 'picture-card',
}"
> >
<template #size> <template #size>
<span <span

View File

@ -0,0 +1,32 @@
import { ref } from 'vue';
export function useImageType() {
const imageListTypes = ['text', 'picture', 'picture-card'] as const;
const imageListOptions = imageListTypes.map((str) => ({
label: str,
value: str,
}));
const currentImageListType =
ref<(typeof imageListTypes)[number]>('picture-card');
return {
imageListOptions,
currentImageListType,
};
}
export function useFileType() {
const fileListTypes = ['text', 'picture'] as const;
const fileListOptions = fileListTypes.map((str) => ({
label: str,
value: str,
}));
const currentFileListType = ref<(typeof fileListTypes)[number]>('text');
return {
fileListOptions,
currentFileListType,
};
}

View File

@ -5,10 +5,12 @@ import { h, ref } from 'vue';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Alert, Card, Modal, Switch } from 'ant-design-vue'; import { Alert, Card, Modal, RadioGroup, Switch } from 'ant-design-vue';
import { FileUpload, ImageUpload } from '#/components/upload'; import { FileUpload, ImageUpload } from '#/components/upload';
import { useFileType, useImageType } from './hook';
const singleImageId = ref('1905537674682916865'); const singleImageId = ref('1905537674682916865');
const singleFileId = ref('1905191167882518529'); const singleFileId = ref('1905191167882518529');
const multipleImageId = ref<string[]>(['1905537674682916865']); const multipleImageId = ref<string[]>(['1905537674682916865']);
@ -29,6 +31,9 @@ function customAccept(accept: string) {
} }
const showComponent = ref(true); const showComponent = ref(true);
const { imageListOptions, currentImageListType } = useImageType();
const { fileListOptions, currentFileListType } = useFileType();
</script> </script>
<template> <template>
@ -135,6 +140,37 @@ const showComponent = ref(true);
挂载/卸载组件: <Switch v-model:checked="showComponent" /> 挂载/卸载组件: <Switch v-model:checked="showComponent" />
<FileUpload v-if="showComponent" v-model:value="singleFileId" /> <FileUpload v-if="showComponent" v-model:value="singleFileId" />
</Card> </Card>
<Card title="图片: listType控制上传样式" size="small">
<RadioGroup
v-model:value="currentImageListType"
:options="imageListOptions"
button-style="solid"
option-type="button"
/>
<ImageUpload
class="mt-2"
v-model:value="singleImageId"
:list-type="currentImageListType"
/>
</Card>
<Card title="文件: listType控制上传样式" size="small">
<div class="mb-2 text-red-500">
注意文件上传不支持`picture-card`类型
</div>
<RadioGroup
v-model:value="currentFileListType"
:options="fileListOptions"
button-style="solid"
option-type="button"
/>
<FileUpload
class="mt-2"
v-model:value="singleFileId"
:list-type="currentFileListType"
/>
</Card>
</div> </div>
</Page> </Page>
</template> </template>