首先是整体代码
这个项目是用了v-for的多个上传,分别进行各自的上传,预览,回显。
可以适当无视v-if等
<el-upload
:ref="'upload'+item.whNo"
:class="[{disabled:fileMap.get(item.whNo)!==undefined},{disabled:item.receiptStatus==='正常'},'uploadclass']"
:action="uploadUrl"
:file-list="photoList[i]"
:data="getuploadP(item)"
list-type="picture-card"
:on-success="function (response, file, fileList){ return uploadSuccess(response, file, fileList, i)}"
:on-remove="handleRemove"
:before-upload="beforeAvatarUpload"
:on-error="uploadError"
accept=".jpg,.png,.BMP"
:on-change="function (file, fileList) { return changePic(file, fileList, item.whNo)}"
>
<img src="@/assets/img/numberBack/tp.png" style="padding-top: 30px">
<div slot="file" slot-scope="{file}">
<img
class="el-upload-list__item-thumbnail"
:src="file.url"
>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in" />
</span>
<span
v-if="!disabled&&shangyibudaohegui!=='2'&&quanxianxx==='1'&&quxiaobtnxy"
class="el-upload-list__item-delete"
@click="handleRemove(file,item.whNo)"
>
<i class="el-icon-delete" />
</span>
</span>
</div>
</el-upload>
<!--放大用的-->
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<div class="uploadbtn">
<!-- <el-button size="mini" icon="el-icon-full-screen" @click="yulan(i)">预览</el-button>-->
<el-button v-if="fileMap.get(item.whNo)===undefined&&item.receiptStatus!=='正常'&&quanxianxx==='1'" class="cxscbtn" icon="el-icon-upload2" size="mini" style="width: 70px" main @click="cxsc('upload'+item.whNo, 0)">上传</el-button>
<el-button v-else-if="fileMap.get(item.whNo)!==undefined&&item.receiptStatus==='正常'&&shangyibudaohegui!=='2'&&quanxianxx==='1'&&quxiaobtnxy" class="cxscbtn" icon="el-icon-refresh-left" size="mini" main @click="cxsc('upload'+item.whNo, 1)">重新上传</el-button>
<p class="tsp">支持jpg/png/bmp等格式,不超过5M</p>
<!-- <p class="tsp" v-if="quanxianxx==='1'" style="color: red">图片上传,请勿重复上传</p> -->
</div>
然后是data
//这个uploadUrl知道咋回事得了
uploadUrl: '.' + process.env.VUE_APP_BASE_API + '/api/complianceCheck/uploadFile',
fileMap: new Map(),
dialogImageUrl: '',
dialogVisible: false,
photoList: [],
先进行el-upload的记录
<el-upload
:ref="'upload'+item.whNo" // $refs来区分每一个上传。 item.whNo我需在意,是项目一个参数
:class="[{disabled:fileMap.get(item.whNo)!==undefined},{disabled:item.receiptStatus==='正 常'},'uploadclass']" //项目上传样式状态的改变
:action="uploadUrl" //必传参数,是地址
:file-list="photoList[i]" //做回显时才添加的,记录了页面初次进入调用接口获取的回显数据。i不用说,就是v-for的下标
:data="getuploadP(item)" //附带参数,,没啥说的
list-type="picture-card"
:on-success="function (response, file, fileList){ return uploadSuccess(response, file, fileList, i)}"//成功回调,这个写法学到了
:on-remove="handleRemove" //文件列表移除文件时的钩子
:before-upload="beforeAvatarUpload" //上传文件之前的钩子
:on-error="uploadError" //失败回调
accept=".jpg,.png,.BMP" //接受上传的文件类型
:on-change="function (file, fileList) { return changePic(file, fileList, item.whNo)}" //文件状态改变时的钩子,在这里做了一些事情
>
<img src="@/assets/img/numberBack/tp.png" style="padding-top: 30px"> //组件哪个加号图片,随便换
<div slot="file" slot-scope="{file}">
<img
class="el-upload-list__item-thumbnail"
:src="file.url" //上传,回显的图片都显示在这里了
>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)" //组件自带放大预览
>
<i class="el-icon-zoom-in" />
</span>
<span
v-if="!disabled&&shangyibudaohegui!=='2'&&quanxianxx==='1'&&quxiaobtnxy"
class="el-upload-list__item-delete"
@click="handleRemove(file,item.whNo)" 图片删除功能
>
<i class="el-icon-delete" />
</span>
</span>
</div>
</el-upload>
<!--放大用的--> 就是那个自带的预览
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<div class="uploadbtn">
<div class="uploadbtn">
<!-- <el-button size="mini" icon="el-icon-full-screen" @click="yulan(i)">预览</el-button>--> 没有了,自己琢磨吧
<el-button v-if="fileMap.get(item.whNo)===undefined&&item.receiptStatus!=='正常'&&quanxianxx==='1'" class="cxscbtn" icon="el-icon-upload2" size="mini" style="width: 70px" main @click="cxsc('upload'+item.whNo, 0)">上传</el-button> //无视v-if,这不就用上ref了么
<el-button v-else-if="fileMap.get(item.whNo)!==undefined&&item.receiptStatus==='正常'&&shangyibudaohegui!=='2'&&quanxianxx==='1'&&quxiaobtnxy" class="cxscbtn" icon="el-icon-refresh-left" size="mini" main @click="cxsc('upload'+item.whNo, 1)">重新上传</el-button>
<p class="tsp">支持jpg/png/bmp等格式,不超过5M</p>
</div>
methods
getuploadP(item) { // :data的,上传时附带的额外参数
return {
uploadType: 1,
dcNo: item.dcNo,
whNo: item.whNo,
receiptConsignLetterAddress: item.receiptConsignLetterAddress,
projectid: this.projectid
}
},
uploadSuccess(response, file, fileList, index) { //上传成功后有用的信息扔到form里了
console.log(response)
this.sxcg.push(response.data.imgUrl)
this.form[index].objKey = response.data.objKey
this.form[index].receiptStatus = response.data.receiptStatus
this.form[index].imgUrl = response.data.imgUrl
this.form.push({})
this.form.pop()
},
beforeAvatarUpload(file) { //这不就上传前的验证嘛,讲真,还没有测试过,不知道有效了没。。
const isJPG = file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/BMP'
const isLt2M = file.size / 1024 / 1024 < 5
if (!isJPG) {
this.$message.error('上传图片只能是 JPG,PNG,BMP 格式!')
}
if (!isLt2M) {
this.$message.error('文件大小不能超过5M')
}
return isJPG && isLt2M
},
uploadError() { //失败
this.$message.error('上传失败,请重新上传')
},
handlePictureCardPreview(file) { 自带的预览功能
this.dialogImageUrl = file.url
this.dialogVisible = true
},
下面几个我自认需要学习一下
handleRemove(file, id) { //图片的删除
this.$refs['upload' + id][0].clearFiles() //组件方法
this.fileMap.delete(id)
this.$forceUpdate() //vue强制更新
},
changePic(file, fileList, id) { //on-change方法
if (fileList.length > 1) {
fileList.shift()
}
this.fileMap.set(id, { file: file, disSign: true })
this.$forceUpdate()
},
hqwthxx() { 页面初次加载,获取页面数据,回显也在这里,应用了base64的转换
// 别删
const body = [] 发送给后端的参数,依照项目多种情况的判断,可无视
if (this.mainidnum || this.mainIdd) {
if (this.mainidnum) {
if (this.dcno && this.whno) {
console.log('this.dcno && this.whno', this.dcno && this.whno)
body.push({
dcNo: this.dcno,
whNo: this.whno,
mainId: this.mainidnum
})
}
} else {
if (this.dcno && this.whno) {
console.log('this.dcno && this.whno', this.dcno && this.whno)
body.push({
dcNo: this.dcno1,
whNo: this.whno1,
mainId: this.mainIdd
})
}
}
} else {
if (this.bcfs === '2') {
console.log('this.bcfs')
body.push({
dcNo: this.pszx,
whNo: this.qcMdc
})
} else {
this.target.forEach(item => {
console.log('target.forEach', this.target)
body.push({
dcNo: this.pszx,
whNo: item.id
})
})
}
}
Axios.post('/api/complianceCheck/getReceiptConsignList', body).then(res => {
res.data.receiptConsignVoList.forEach((item, index) => {
this.photoList.push([]) //这里,回显信息放到photoList,([])是组件要求,需要是[]
this.toBase64(item.receiptConsignAddress, item.whNo, index) //base64转换,参数是图片地址,项目应用信息一个,index下标,
})
this.form = res.data.receiptConsignVoList //信息放到form里了
})
},
base64,没啥说的,但是this.$set的用法你不学一下么
toBase64(imgUrl, kfzxh, index) {
let imageUrl = ''
console.log('toBase64')
if (imgUrl !== null && imgUrl !== '') {
console.log('toBase64->imgUrl is not null')
imageUrl = imgUrl.replace('http://storage.jd.local', '/getJssImage')
}
console.log('imageUrl->' + imageUrl)
// 一定要设置为let,不然图片不显示
const image = new Image()
// 解决跨域问题
image.crossOrigin = ''
image.setAttribute('crossOrigin', 'anonymous')
image.src = imageUrl
// image.onload为异步加载
image.onload = () => {
var canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
var context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
var quality = 0.8
// 这里的dataurl就是base64类型
// 使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
const dataurl = canvas.toDataURL('image/jpeg', quality)
this.$set(this.photoList, index, [new Photo(kfzxh, dataurl)])//放到photoList里,替换掉第index个,替换内容为[new Photo(kfzxh, dataurl)]
}
},
对了,别忘了这个
class Photo {
constructor(name, url) {
this.name = name
this.url = url
}
}
export default { //写哪知道了吧。。。
然后是上传按钮和重新上传按钮
百度发现了$refs[‘upload-inner’].handleClick()
cxsc(id, sign) {
if (sign === 0) { // 上传
this.$refs[id][0].$refs['upload-inner'].handleClick()
} else { // 重新上传
this.$refs[id][0].$refs['upload-inner'].handleClick()
}
console.log('cxsc')
}
差个小样式,不要丢了
图片上传一个后none掉上传框
.disabled >>> .el-upload--picture-card {
display: none;
}