这里是我参考的地址 https://blog.csdn.net/aiguo94/article/details/111832776
他里面有后台可以参考的,我这里只写前端的
下载依赖 cnpm install ali-oss
html 部分,我这里是用的组件+element对话框+element上传文件功能
先说一下element的上传文件吧,我遇到的坑,上传文件本身是有自动上传的功能的,也就是一般会调用后台接口,但是oss是需要先在后台拿到一些参数,在上传,所有
action="#" 被我置空,:auto-upload改为"false",auto-upload就是自动上传的参数,具体的可以看一下element的文档,auto-upload改为false就改成手动上传了,所以在选择文件时,想获取到文件的信息,别的事件我用都不好使,只有个
:on-change事件好用,所以我就用的这个,在这个事件里获取了文件的信息,名字,类型,大小等
这里就是调用接口,取后台给的参数

官网是这么说的:官网地址 https://help.aliyun.com/document_detail/111268.html?spm=a2c4g.11186623.6.1115.601728476iEKUl


我写的思路表达完毕,现在上完整代码,这里是组件内的,
<template>
<div>
<el-dialog title="上传文件" :visible.sync="visible" width="30%" height="200px" center :close-on-click-modal="false" @close="close">
<el-form>
<el-form-item label="选择文件:" label-width="120px">
<el-upload class="upload-demo inlineBlock"
ref="bigMap4UploadFile"
action="#"
:auto-upload="false"
:show-file-list="false"
:accept='parameter.accept'
:on-change="beforeAvatarUpload">
<el-button size="small" type="primary"><i class="el-icon-plus"></i> 选择文件</el-button>
</el-upload>
<!-- <el-button id="uploadBtn" size="small" @click="upload()" style="background-color:rgba(86, 192, 13, 0.93);color: white;"> <i class="el-icon-upload"></i> 开始上传</el-button> -->
<!-- <el-button id="stopBtn" size="small" v-show="showValue === 1" @click="stop()" style="background-color: indianred;color: white;margin-left:10px"> <i class="el-icon-close"></i> 取消大文件上传</el-button> -->
</el-form-item>
<el-form-item label="文件支持格式:" label-width="120px">
<span class="el-upload__tip">{{parameter.accept}}</span>
</el-form-item>
</el-form>
<!-- <h2 id='status'>{{statusMsg}}</h2> -->
<!-- <img v-show="imgSrc" :src="imgSrc" alt="" class="img"> -->
<h3 v-show="img" class="relH3">{{img}} <i class="el-icon-delete absRight" @click="clearInfo"></i></h3>
<el-progress :percentage="progressValue" v-show="showValue==1"></el-progress>
<span slot="footer" class="dialog-footer">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="confirm(true)" :disabled="buttonControl">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import $api from '@api'
// import { mapGetters } from 'vuex'
const OSS = require('ali-oss')
var credentials = null // STS凭证
var ossClient = null // oss客户端实例
export default {
data () {
return {
statusMsg: '',
progressValue: 0,
showValue: 0,
imgSrc: null,
img: null,
visible: false, // 弹框是否显示
fileInfo: null, // 选择文件信息
backObj: {},
buttonControl: false
}
},
model: {
prop: 'videoUrl',
event: 'change'
},
/**
* parameter:Object 参数格式
* accept: 文件格式 eg: 'image/jpg,image/gif,image/png,image/jpeg,image/bmp,image/svg'
size: 限制最大文件 eg: 10 type:number
folder: 必填项 后台服务功能模块 各个模块不同,可以问后台此参数传什么 eg: user //个人中心
# 会员中心 customer
# 工具服务 utility
# 设备租赁 rent
# 劳动力 uber
# 部品 bpsc
# 交易 trade
# 建筑产品 jzsc
# 供需平台 snd
# 模型 model
modelFlag: 上传模型传1 ,默认不传
*/
props: {
videoUrl: String,
parameter: Object
},
// computed: {
// ...mapGetters([
// 'bucketUrl'
// ])
// },
mounted () {
this.init()
},
methods: {
init () {
this.visible = true
},
// 确定
confirm () {
this.visible = false
if (this.backObj.name) {
this.$emit('change', this.backObj)
} else {
this.$emit('change', {})
}
},
// 关闭
close () {
this.visible = false
// console.log('关闭')
this.$emit('close', {})
},
// 选择文件
beforeAvatarUpload (file) {
// 获取文件名字,取到文件类型,就是文件后缀,为避免不同设备后缀大小写不一致,统一改成大写
var type
if (file.name || file.raw.type === '') {
var arr = file.name.split('.')
type = arr[arr.length - 1].toUpperCase()
}
// this.parameter.accept这个值是组件里的参数,是控制上传文件格式的
if (this.parameter.accept && this.parameter.accept.toUpperCase().indexOf(type) <= 0) {
this.$message({ type: 'error', message: '格式不正确!', duration: 1000 })
return false
}
if (this.parameter.size) {
const isLt2M = file.size / 1024 / 1024 < this.parameter.size
if (!isLt2M) {
this.$message.error('大小不能超过 ' + this.parameter.size + 'MB!')
return false
}
}
this.buttonControl = true // 控制确定按钮不能点击,上传成功才可点击
this.fileInfo = file
this.img = file.name
this.upload()
},
// 清空
clearInfo () {
this.statusMsg = ''
this.$refs.bigMap4UploadFile.value = ''
this.progressValue = 0
this.showValue = 0
this.img = null
this.backObj = {}
},
// 上传
upload () {
this.statusMsg = '上传中'
$api.user.getStsToken({
modelFlag: this.parameter.modelFlag
}).then(({ data }) => {
// console.log(data)
if (data && data.head.retCode === '0000') {
credentials = data.body
const { accessKeyId, accessKeySecret, securityToken, bucketName } = credentials
if (!this.parameter.folder) return this.$message({ type: 'error', message: '服务功能模块未上传!', duration: 1000 })
ossClient = new OSS({
accessKeyId: accessKeyId,
accessKeySecret: accessKeySecret,
stsToken: securityToken,
bucket: bucketName, // utility
secure: true,
region: 'oss-cn-beijing', // todo
folder: this.parameter.folder
})
if (ossClient) {
var { raw } = this.fileInfo
var fileList = [raw]
fileList.forEach(file => {
// 如果文件大学小于分片大小,使用普通上传,否则使用分片上传
// if (file.size < partSize) {
// this.showValue = 0
// this.commonUpload(file)
// } else {
this.showValue = 1
this.multipartUpload(file)
// }
})
} else {
this.$message({ type: 'error', message: '服务端响应异常!', duration: 1000 })
this.statusMsg = 'initOSSClient异常空,请刷新重试或联系管理员'
}
} else {
this.$message({ type: 'error', message: '服务端响应异常!', duration: 1000 })
this.statusMsg = 'sts临时凭证获取失败,请刷新重试或联系管理员'
}
}).catch(err => {
this.$message({ type: 'error', message: '服务端响应异常!', duration: 1000 })
this.statusMsg = err + 'initOSSClient异常,请刷新重试或联系管理员'
})
},
// 添加文件夹名字
getDateFolder () {
const t = new Date()
let timeStr = ''
timeStr = timeStr + t.getFullYear() // 年
timeStr = timeStr + (t.getMonth() + 1)// 月,因为从0开始,所以需要加1
timeStr = timeStr + t.getDate() // 日
return timeStr
},
// 普通上传
commonUpload (file) {
// var fileName = file.name
var newFileName = new Date().getTime() + Math.random().toString(36).substr(2) + file.name.substr(file.name.lastIndexOf('.'))
return ossClient.put(this.parameter.folder + '/' + newFileName, file).then(result => {
// console.log(`Common upload ${file.name} succeeded, result === `, result)
this.imgSrc = result.url // 此页面可用来展示图片
this.backObj = result
this.backObj.size = file.size
this.backObj.oldName = file.name
this.buttonControl = false
}).catch(err => {
this.statusMsg = '上传失败'
this.buttonControl = true
console.log(`Common upload ${file.name} failed === `, err)
})
},
// 分片上传
multipartUpload (file) {
// oss上传到服务器上的名字 我这是后台服务名字+时间戳+6位随机数
var newFileName = new Date().getTime() + Math.random().toString(36).substr(2) + file.name.substr(file.name.lastIndexOf('.'))
return ossClient.multipartUpload(this.parameter.folder + '/' + newFileName, file, {
progress: this.onMultipartUploadProgress
}).then(result => {
this.statusMsg = '上传成功'
this.backObj = result
this.backObj.size = file.size
this.backObj.oldName = file.name
this.buttonControl = false
// console.log('上传成功')
}).catch(err => {
console.log('上传失败')
this.statusMsg = '上传失败'
console.log(`Multipart upload ${file.name} failed === `, err)
this.progressValue = 0
this.showValue = 0
this.buttonControl = true
})
},
// 分片上传进度改变回调
onMultipartUploadProgress (progress, checkpoint) {
// console.log(`${checkpoint.file.name} 上传进度 ${progress}`)
// checkpoints[checkpoint.uploadId] = checkpoint
this.progressValue = Math.round(progress * 100)
},
// 停止上传
stop () {
this.statusMsg = '停止上传'
if (ossClient) {
ossClient.cancel()
} else {
this.statusMsg = '停止失败'
}
}
}
}
</script>
<style scoped lang="scss">
.avatar {
width: 178px;
height: 178px;
display: block;
}
.img{
width: 178px;
height: 178px;
}
.relH3{
padding: 0 27px;
position: relative;
}
.absRight{
position: absolute;
right:10px;
}
</style>
这里是引用组件所写的,有点散,我就上图了



