场景需求:弹窗进行表单提交,其中上传图片需要上传到阿里云oss,根据上传阿里云后的回调参数确定图片的url地址,然后将所有图片的url地址组成一个数组连同表单的其他值一同传给后端。而上传组件需要做的就是做单个的图片上传到阿里云oss,并返回上传回调后的url,不要问为什么不做批量上传,懂得自然会懂,不懂的自己实践下即可懂。
Uploadimg.vue上传组件代码:
<template>
<div class="uploadimg">
<el-upload
:action="url"
list-type="picture-card"
accept="image/*"
:data="basedata"
:file-list="fileList"
:limit="limit"
:auto-upload="true"
:on-preview="handlePictureCardPreview"
:on-success="handleSuccess"
:before-upload="handleUpload"
:on-exceed="handleExceed"
:on-remove="handleRemove">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible" append-to-body>
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
import { filePolicy } from "@/api/upload"
export default {
name:'Uploadimg',
props:{
limit:Number,
filelist:Array(),
},
data() {
return {
url:'',
fileList:[],
// filelist:[], //上传文件url列表
basedata:{},
dialogImageUrl: '',
dialogVisible: false
};
},
mounted() {
this.fileList=this.filelist.map(item=>{return {url:item}})
},
methods: {
handleUpload(file){
console.log("开始上传:",file);
const that=this
return new Promise((resolve, reject) => {
filePolicy().then(key=>{
that.url=key.data.data.host;
var name=file.name;
key.data.data.OSSAccessKeyId=key.data.data.accessid;
key.data.data.key=key.data.data.dir+'/'+file.uid+name;
delete key.data.data.callback
that.basedata=key.data.data;
var img=key.data.data.cdnHost+'/'+key.data.data.key;
that.filelist.push(img);
resolve();
}).catch(err => {reject(err);})
})
},
handleSuccess(response, file, fileList){
console.log("上传成功:",response,file, fileList);
this.fileList=fileList;
this.$emit("getfile",this.filelist);
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 ${this.limit} 个文件`);
},
handleRemove(file, fileList) {
console.log("删除文件:",file);
this.fileList=fileList;
var f = this.filelist.find(item=>item.indexOf(file.uid)!=-1);
var i = this.filelist.indexOf(f);
this.filelist.splice(i,1);
this.$emit("getfile",this.filelist);
},
handlePictureCardPreview(file) {
console.log("文件预览:",file);
this.dialogImageUrl = file.url;
this.dialogVisible = true;
}
},
}
</script>
这里的filePolicy是一个promise异步请求,主要获取阿里云的上传秘钥。代码如下
import request from '@/request/request'
export function filePolicy() {
return new Promise((resolve, reject)=>{
request.get('/user/file/policy',{}).then(res=>{
console.log("秘钥:",res.data);
resolve(res);
}).catch(err=>{console.log("网络错误",err);});
})
}
我这里后端给我返回的参数主体结构如下,如果你们后端不是如此返回的话,那我就不知道了:
组件使用方式:limit参数代表允许上传图片的数量,filelist图片显示的数组,因为涉及到组件和父组件图片数组参数的来回传值,因此加了一个中间参数fileList。
<Uploadimg :limit="2" :filelist="form.certificate" @getfile="filelist" v-if="dialogFormVisible"></Uploadimg>
methods:{
//上传的图片列表
filelist(list){
console.log("图片:",list)
this.form.certificate=list;
},
}
components:{
Uploadimg:Uploadimg,
}
最后显示的结果是: