如何基于 vue3+el-upload 二次封装上传文件组件到阿里云 oss 附进度条 一、创建生成全局唯一标识符 方法 二、导入计算文件Md5(spark-md5) 三、安装依赖ali-oss 四、创建导出ali-oss 方法 五、创建上传文件 组件(完整代码) 六、引入使用组件
一、创建生成全局唯一标识符 方法
export function newGuid ( ) { function S4 ( ) { return ( ( ( 1 + Math. random ( ) ) * 0x10000 ) | 0 ) . toString ( 16 ) . substring ( 1 ) } return S4 ( ) + S4 ( ) + S4 ( ) + S4 ( ) + S4 ( ) + S4 ( ) + S4 ( ) + S4 ( )
}
二、导入计算文件Md5(spark-md5)
npm i spark-md5
三、安装依赖ali-oss
npm i ali-oss
四、创建导出ali-oss 方法
在utils文件夹下 创建alioss.ts,并接收所需要的阿里云oss地区、id、密钥、远程仓库名称
import OSS from 'ali-oss'
export function client < T > ( accessKeyId: T , accessKeySecret: T ) {
console . log ( '接收到的' , accessKeyId, accessKeySecret) var clients = new OSS ( { region: 'oss-cn-beijing' , accessKeyId, secure: true , accessKeySecret, bucket: 'cangku' , } ) return clients
}
五、创建上传文件 组件(完整代码)
创建封装上传文件组件 (代码中需填写阿里云oss的id和密钥)
< template> < div> < el-progressv-if = " showPercentage" style = " margin-bottom : 15px" :text-inside = " true" :stroke-width = " 20" :percentage = " percentage" striped striped-flow /> < el-uploadclass = " upload-demo" :drag = " drag" :limit = " limit" :disabled = " disabled" :auto-upload = " autoUpload" :accept = " accept" :show-file-list = " showFileList" :action = " action" :multiple = " multiple" :http-request = " httpRequest" :before-upload = " beforeUpload" :on-progress = " uploadFileProcess" :on-success = " handleAvatarSuccess" :on-remove = " handleRemove" :on-exceed = " handleExceed" :on-change = " handleChange" > < div v-if = " drag" > < el-icon class = " el-icon--upload" > < upload-filled /> </ el-icon> < div class = " el-upload__text" > 将文件拖到此处,或< em> 点击上传</ em> </ div> </ div> < div v-else > < el-button type = " primary" > 点我上传</ el-button> </ div> </ el-upload> </ div>
</ template>
< script setup lang = " ts" >
import { ref } from 'vue'
import { UploadFilled } from '@element-plus/icons-vue'
import SparkMD5 from 'spark-md5'
import { newGuid } from '@/utils/guid'
import { client } from '@/utils/alioss'
import { ElMessage } from 'element-plus'
import type { UploadProps } from 'element-plus'
const showPercentage = ref ( false )
const percentage = ref ( 0 ) const props = defineProps ( { action : { type : String, } , multiple : { type : Boolean, default : ( ) => false , } , showFileList : { type : Boolean, default : ( ) => true , } , drag : { type : Boolean, default : ( ) => true , } , accept : { type : String, } , limit : { type : Number, } , disabled : { type : Boolean, default : ( ) => false , } , autoUpload : { type : Boolean, default : ( ) => true , } ,
} )
const getFileMd5 = ( file : any) => { return new Promise ( ( resolve, reject ) => { const spark = new SparkMD5. ArrayBuffer ( ) console. log ( 'spark' , spark) const fileReader = new FileReader ( ) console. log ( 'fileReader' , fileReader) fileReader. onload = ( e : any) => { console. log ( '打印e' , e) spark. append ( e. target. result) resolve ( spark. end ( ) ) } fileReader. onerror = ( ) => { reject ( '' ) } fileReader. readAsArrayBuffer ( file. file) } )
}
const getExtension = ( file : File) => { if ( file) { const regex = / (?:\.([^.]+))?$ / const result = regex. exec ( file. name) return result?. [ 1 ] || null } return null
}
const httpRequest = async ( file : any) => { ElMessage ( { message : '开始上传,请等待!' , type : 'warning' , } ) showPercentage. value = true console. log ( '自定义上传了文件' , file) const fileMd5 = await getFileMd5 ( file) console. log ( '打印文件的md5' , fileMd5) const fileGuid = newGuid ( ) console. log ( '打印生成的文件名称' , fileGuid) const fileSuffix = getExtension ( file. file) console. log ( '打印获取的文件后缀' , fileSuffix) const newFileName = fileGuid + '.' + fileSuffixconsole. log ( '生成新文件名' , newFileName) let AccessKeyId = 'xxxx' let AccessKeySecret = 'xxxx' let res = await client ( AccessKeyId, AccessKeySecret) . multipartUpload ( newFileName, file. file, { progress, parallel : 4 , partSize : 1024 * 1024 * 1 , timeout : 120000 , } ) console. log ( '打印上传的结果' , res) if ( res. res. statusCode === 200 ) { ElMessage ( { message : '上传成功!' , type : 'success' , } ) } else { file. onError ( '上传失败' ) }
}
const progress = ( progress : any, checkpoint : any) => { console. log ( '上传进度' , progress) percentage. value = progress. toFixed ( 2 ) * 100 console. log ( '分片上传的断点信息' , checkpoint)
}
const beforeUpload : UploadProps[ 'beforeUpload' ] = ( file ) => { console. log ( '上传文件之前的钩子函数' , file)
}
const uploadFileProcess : UploadProps[ 'onProgress' ] = ( ) => { console. log ( '文件上传时的钩子函数' )
}
const handleAvatarSuccess : UploadProps[ 'onSuccess' ] = ( response, uploadFile
) => { console. log ( '文件上传成功时的钩子' ) setTimeout ( ( ) => { showPercentage. value = false percentage. value = 0 } , 300 )
}
const handleRemove : UploadProps[ 'onRemove' ] = ( file, uploadFiles ) => { console. log ( '文件列表移除文件时的钩子' )
}
const handleExceed : UploadProps[ 'onExceed' ] = ( ) => { console. log ( '超出限制时,执行的钩子函数' )
}
const handleChange : UploadProps[ 'onChange' ] = ( ) => { console. log ( '文件状态改变时的钩子函数' )
}
</ script> < style scoped lang = " scss" > </ style>
六、引入使用组件
const UploadFile = defineAsyncComponent ( ( ) => import ( '@/components/uploadFile/index.vue' )
)
< UploadFile> < / UploadFile>