自定义上传附件方法
import { Notify } from 'vant'
export interface UploadOptions {
/**是否多选 */
multiple?: boolean
/**限制上传类型 */
accept?: string
/**限制上传类型错误提示 */
acceptErrorMsg?: string
/**最大上传数量 */
limit?: number
/**单个上传大小(单位为MB) */
fileSize?: number
}
export interface UploadFile {
/**附件地址 */
appendixUrl: string
/**附件名称 */
appendixName: string
}
type UploadSuccess = {
data: { ossUrl: string }
}
/**默认支持图片和pdf */
const defaultAccept = '.jpe,jpeg,.jpg,.png,.pdf'
export default function upload(options: UploadOptions = {}, echoFileList: Obj[] = []): Promise<UploadFile[]> {
return new Promise((resolve, reject) => {
const { multiple = true, accept = defaultAccept, acceptErrorMsg = '', limit = 1, fileSize = 50 } = options
// 创建文件选择元素
const input: HTMLInputElement = document.createElement('input')
input.type = 'file'
input.multiple = multiple
input.accept = accept
input.style.display = 'none'
document.body.appendChild(input)
input.click()
input.addEventListener('change', e => {
const files: Array<File> = Object.values((e.target as HTMLInputElement).files ?? [])
document.body.removeChild(input)
// 判断是否超出上传数量限制
if (files.length > limit - echoFileList.length) {
Notify({ type: 'danger', message: `最大上传数量为${limit}个` })
reject({ errorType: 'limitError', files })
return
}
// 判断是否超出上传文件大小限制
if (files.some(i => i.size / 1024 ** 2 > fileSize)) {
Notify({ type: 'danger', message: `单个文件最大为${fileSize}MB` })
reject({ errorType: 'fileSizeError', files })
return
}
//判断上传文件的类型是否错误
if (handleAccept(files, accept)) {
Notify({ type: 'danger', message: acceptErrorMsg || `上传文件只能是${accept}格式` })
reject({ errorType: 'acceptError', files })
return
}
handleUploadHttp(files, resolve)
})
})
}
/**校验上传类型 */
function handleAccept(files: File[], accept: string) {
return files.some(file => {
const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1)
return accept.indexOf(fileSuffix) === -1
})
}
/**上传接口 */
async function handleUploadHttp(files: File[], resolve) {
//fileUploader: 上传接口 使用时请更换为你自己的上传接口
const successFiles = await (Promise.all(files.map(file => fileUploader('/common/file/uploadMultipartFile', { file }))) as Promise<Array<UploadSuccess>>)
const resFile: Array<UploadFile> = successFiles.map((item, index) => {
return {
appendixUrl: item.data?.ossUrl, // 附件地址
appendixName: files[index].name, // 附件名称
}
})
resolve(resFile)
}
把方法挂载到Vue原型上
Vue.prototype.$upload = upload
组件内使用
<script lang="tsx">
import { Vue, Component } from 'vue-property-decorator'
@Component
export default class Test extends Vue {
render() {
return <button onClick={this.handleUpload}>点击上传</button>
}
handleUpload() {
this.$upload().then(res => {
console.table(res)
})
}
}
</script>