123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- <template>
- <a-upload
- :file-list="[]"
- :multiple="false"
- :before-upload="onBeforeUpload"
- :accept="extnames.map(ext => `.${ext}`).join(',')"
- >
- <a-button type="primary" :disabled="disabled || !!file">
- <upload-outlined></upload-outlined>
- 上传
- </a-button>
- </a-upload>
- <ol class="desc">
- <li>支持{{ extxTip }}文件格式;</li>
- <li>最大支持上传{{ maxSizeTip }};</li>
- <template v-if="tips">
- <li v-for="tip in tips" :key="tip">{{ tip }}</li>
- </template>
- </ol>
- <div v-if="file" class="action">
- <p>{{ typeof file === 'string' ? file : file.name }}</p>
- <delete-outlined
- v-if="!disabled"
- class="icon"
- @click="emit('update:file', undefined)"
- />
- </div>
- </template>
- <script lang="ts" setup>
- import { message } from 'ant-design-vue'
- import { getExtname } from '@/shared'
- import { computed } from 'vue'
- import type { UploadProps } from 'ant-design-vue'
- export type BUploadProps = {
- disabled?: boolean
- file?: File | string
- maxSize: number
- extnames: string | string[]
- tips?: string[]
- }
- const props = defineProps<BUploadProps>()
- const emit = defineEmits<{
- (e: 'update:file', v: BUploadProps['file']): void
- }>()
- const maxMB = computed(() => props.maxSize * 1024 * 1024)
- const maxSizeTip = computed(() =>
- props.maxSize > 1024 ? props.maxSize / 1024 + 'GB' : props.maxSize + 'MB'
- )
- const extnames = computed(() =>
- (Array.isArray(props.extnames) ? props.extnames : [props.extnames]).map(ext =>
- ext.toLowerCase()
- )
- )
- const extxTip = computed(
- () =>
- extnames.value.map(ext => `.${ext}`).join('、') +
- (extnames.value.length > 1 ? '等' : '')
- )
- const onBeforeUpload: UploadProps['beforeUpload'] = file => {
- const ext = getExtname(file.name)?.toLocaleLowerCase()
- if (!ext || !extnames.value.includes(ext)) {
- message.error(`仅支持${extxTip.value}文件格式`)
- } else if (file.size > maxMB.value) {
- message.error(`最大支持上传${maxSizeTip.value}`)
- } else {
- emit('update:file', file)
- }
- return false
- }
- </script>
- <style lang="scss" scoped>
- .desc {
- margin-top: 16px;
- color: #999999;
- padding-left: 20px;
- }
- .action {
- font-size: 14px;
- color: #323233;
- display: flex;
- align-items: center;
- p {
- margin: 0;
- word-break: break-all;
- }
- .icon {
- margin-left: 10px;
- color: #c8c8c8;
- cursor: pointer;
- transition: color 0.3s ease;
- &:hover {
- color: inherit;
- }
- }
- }
- </style>
|