背景
有上传图片的需求
- 上传,限制大小、尺寸格式(用地址存储的图片),只能传一张
- 回显,上传后显示图片,请求接口返回数据,有图片地址的需要直接回显
- 替换,需要能存入新图片
在以上背景下,有一些可复用的代码,可以直接拿来使用。但是使用过程中一些参数的使用不熟悉,故而在此做一个记录
html代码
<el-form-item
label="模块显示图标"
label-width="120px"
prop="mainPicture"
id="validation"
>
<div>
<el-upload
:disabled="seeDetail"
action="billapi/file/uploadImage"
:headers="sessionMessage"
:before-upload="beforeUploadPic"
:on-success="pictureSuccess"
:on-change="pictureChange"
:on-remove="pictureRemove"
:on-preview="pictureView"
:class="{ 'demo-httpRequestImg': httpRequestImg }"
:file-list="picUrlJsonList"
:limit="limitMainPic"
list-type="picture-card"
accept=".jpg, .png, .JPG, .PNG"
>
<i class="el-icon-picture"></i>
</el-upload>
<el-dialog :visible.sync="pictureSee" append-to-body>
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
</div>
<span v-if="!seeDetail" style="color: #999">
上传格式:jpg,png 尺寸 200*200,大小不超过2M
</span>
</el-form-item>
其中 upload承担主要功能,div和span分开主要是为了分行显示。el-dialog是在另外情况显示的,和上传不在一个场景,不需要考虑。我们只看upload内的内容,其中i标记是一个图标,显示在upload方框上的。接下来分析upload标记中的参数:
- disabled 是否上传
- action 图片地址
- headers 上传时携带的请求头设置(因为这个接口需要带token所以设置了这个值)
- 类名设置的值为httpRequestImg这个可以控制是否显示上传框,当httpRequestImg为true时不显示,为flase时显示
- limit 最多图片限制
- file-list 上传文件的数组,设置好this.picUrlJsonList[0].url = url地址,就可以显示url地址的图片
- 其余均可在element-ui查到,不做解释。
vue代码
data() {
return {
//图片专用
rules: {
mainPicture: [
{ required: true, message: '请上传图片', trigger: 'change' }
]
},
//图片相关属性
butLoading: false,
picUrlJsonList: [{ url: '' }],
picUrlJson: [],
httpRequestImg: false,
limitMainPic: 1,
pictureSee: false,
dialogImageUrl: '',
sessionMessage: {
Authorization: sessionStorage.getItem('gm_token')
// Authorization: ` Bearer ${sessionStorge.getItem('gm_token')}`
}
}
},
watch: {
data: {
handler(newVal, oldVal) {
//给图片赋值
if (newVal.iconPic) {
this.picUrlJsonList[0].url = newVal.iconPic
this.httpRequestImg = true
} else {
this.picUrlJsonList = []
}
},
deep: true,
immediate: true
}
},
methods:{
/**
*************************************************************************** 图片处理
**/
beforeUploadPic(file) {
const fileType = file.name.substring(file.name.lastIndexOf('.') + 1)
console.log(fileType, 'fileType')
const items = ['jpg', 'png', 'JPG', 'PNG']
const fileTypeValid = items.includes(fileType)
console.log(fileTypeValid, 'fileValid')
if (!fileTypeValid) {
this.$message.error('上传文件类型不匹配,请上传jpg或png格式的图片')
}
console.log(file)
const size3M = file.size / 1024 / 1024 < 3
if (!size3M) {
this.$message.error(`图片大小不能超过 3Mb`)
}
// 判断大小尺寸
const isSizeWidthHeight = new Promise(function (resolve, reject) {
let width = 200
let height = 200
let _URL = window.URL || window.webkitURL
let img = new Image()
img.onload = function () {
let valid = img.width == width && img.height == height
valid ? resolve() : reject()
}
img.src = _URL.createObjectURL(file)
}).then(
() => {
return file
},
() => {
this.$message({
message: '上传图片图尺寸只能是200*200px!请重新选择!',
type: 'warning'
})
return Promise.reject()
}
)
return fileTypeValid && size3M && isSizeWidthHeight
},
pictureSuccess(response, file, fileList) {
this.data.iconPic = response.data//这个data是父组件返回的查到的要用的数据
console.log(`图片上传成功`)
if (fileList.length >= 1) {
let { mainPicture, ...data } = this.rules
this.rules = data
}
this.$refs.ruleForm.clearValidate('mainPicture')
this.picUrlJsonList = fileList
console.log(this.picUrlJsonList, 'prcUrlJsonList1111111111')
console.log(this.data.iconPic, 'url1111111')
this.picUrlJson = fileList.map(item => {
return response.url
})
console.log(this.picUrlJson, 'this.picUrlJson11111')
this.httpRequestImg = fileList.length >= this.limitMainPic
console.log(this.httpRequestImg, 'httpRequestImg111111')
},
pictureChange(file, fileList) {
// console.log(`图片监听`)
},
pictureRemove(file, fileList) {
console.log(`图片删除`)
if (fileList.length == 0) {
this.rules.mainPicture = [
{ required: true, message: '请上传图片', trigger: 'change' }
]
}
this.$refs.ruleForm.validateField('mainPicture')
this.httpRequestImg = fileList.length >= this.limitMainPic
// this.picUrlJson = fileList.map(item => {
// if (item.id) return item.id
// else return item.response.data.res.id
// })
this.picUrlJsonList = fileList
},
pictureView(file) {
this.pictureSee = true
this.dialogImageUrl = file.url
},
videoHoverOptionView() {
console.log(`放大镜`)
this.videoHoverOptionViewDialog = true
}
/**************************** */
}
样式代码如下:
.demo-httpRequestImg {
::v-deep .el-upload--picture-card {
display: none;
}
}