Vue3 uses van-uploader to solve the problem that some Android models (Xiaomi, vivo, oppo, etc.) cannot upload files
summary
Recently, when I was working on a mobile terminal, I encountered a need to upload attachments. Only the following types of files can be uploaded:
Image files (jpeg, jpg, png)
Document files (pdf, txt, doc, docx, xls, xlsx, ppt, pptx)
Here I used Youzan's upload component, but after going online, I found that there was no problem with Apple phones , but some Android phones had problems. After several modifications and adjusting the restricted file types, uploading was normal! ! ! Congratulations, I recorded the solution here, hoping it can help everyone.
Corresponding attachment format
Image format (limited to png, jpeg, png)
accept="image/jpeg,image/png,image/jpg"
jpeg:image/jpeg
png:image/png
jpg:image/jpg
File format (limited to pdf, doc, docx, ppt, pptx, xls, xlsx)
pdf: application/pdf
doc: application/msword
docx: application/vnd.openxmlformats-officedocument.wordprocessingml.document
ppt: application/vnd.ms-powerpoint
pptx: application/vnd.openxmlformats-officedocument.presentationml.presentation
xls: application/vnd .ms-excel
xlsx:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Text format (limited to txt)
txt: text/plain
File format (limited to zip and rar)
zip:application/zip
rar:application/x-rar-compressed
Component encapsulation
Tip: This is used to determine whether there are restriction types and whether the file size meets the standards
<template>
<van-uploader
ref="uploaderRef"
:before-read="beforeRead"
:accept="acceptType"
:max-size="maxSize"
:max-count="maxCount"
preview-size="55px"
>
<span class="text">{{
text
}}</span>
</van-uploader>
</template>
<script lang="ts" setup>
import { Notify, Toast } from 'vant'
import fileApi from '~/api/file'
const uploaderRef = ref() // 文件实例
interface uploadProps {
acceptType?: string // 接受类型
limit?: number // 限制文件个数
maxSize?: number // 文件大小限制
text?: string
fileExtension?: string // 文件后缀名
imgExtension?: string // 图片后缀名
maxCount?: number
}
interface fileItem {
fileName: string
fileUrl: string
fileType: string
size: number
isImage?: boolean
id?: string
businessId?: string
createTime?: string
unit?: string
}
const emits = defineEmits(['success', 'delete',])
const props = withDefaults(defineProps<uploadProps>(), {
text: '上传附件',
limit: 10,
maxSize: 200,
maxCount: 99,
acceptType:
'image/jpeg, image/jpg, image/png, text/plain, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation ,application/pdf',
fileExtension: 'pdf, txt, doc, docx, xls, xlsx, ppt, pptx',
imgExtension: 'jpeg/jpg/png',
fileList: () => [],
showUploadBtn: true,
type: 'add',
})
// 获得文件后缀名
const getFileExtension = (name: string) => {
const extension = name.substring(name.lastIndexOf('.') + 1).toLowerCase() // 文件后缀
return extension
}
// 文件上传钩子
const beforeRead = (file: any) => {
const extension = file.name
.substring(file.name.lastIndexOf('.') + 1)
.toLowerCase() // 文件后缀
// 判断是否图片类型
const isImage = props.imgExtension.includes(extension)
// 判断是否超过最大上传限制,当前限制了200m
const isMax = file.size / 1024 / 1024 < props.maxSize
if (!isMax) {
Notify({
type: 'danger',
message: `文件大小上限为${props.maxSize}M`,
duration: 1000,
})
return false
}
// 限制上传类型
const isLimit = props.fileExtension.includes(extension) || props.imgExtension.includes(extension)
if (!isLimit) {
Notify({
type: 'danger',
message: `文件上传格式不正确`,
duration: 1000,
})
return false
}
// 通过校验后执行上传文件方法
uploadFile(file)
return true
}
// 唤醒上传文件功能
const openUploader = () => {
uploaderRef.value.chooseFile()
}
const deleteList = (index: number) => {
emits('delete', index)
}
// 上传文件
const uploadFile = async (file: File) => {
Toast.loading({
duration: 0,
message: '上传中...',
forbidClick: true,
})
const formData = new FormData()
formData.append('file', file)
formData.append('transfer', '0')
const { code, data } = await fileApi.uploadFile(formData) // 这里替换成实际项目中的api名称
const extension = file.name
.substring(file.name.lastIndexOf('.') + 1)
.toLowerCase() // 文件后缀
const isImage = props.imgExtension.includes(extension)
if (code.value === 0) {
const fileData = {
fileName: file.name,
fileUrl: data.value.message, // 图片回显
size: file.size,
fileType: getFileExtension(file.name),
isImage,
unit: 'KB',
}
// 抛出成功信息
emits('success', fileData)
Notify({
type: 'success',
message: `上传成功`,
duration: 1000,
})
Toast.clear()
return true
} else {
Notify({
type: 'danger',
message: `上传失败`,
duration: 1000,
})
Toast.clear()
}
}
defineExpose({
openUploader,
})
</script>
<style lang="less" scoped>
.text {
color: #86909c;
font-size: 15px;
display: inline-block;
}
</style>