一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
一、文件单独上传和同接口信息一起上传
需求一、单独上传
录入信息和图片,分成两个接口,图片选中后直接上传,将返回的ID存入录入信息接口的相应字段。
代码如下:
<el-form-item label="营业执照" prop="businessLicense">
<label slot="label">营业执照 (请上传20M以内的图片)</label>
<el-upload :disabled="justCheck" ref="proUpload" action="`后台文件上传接口`" list-type="picture-card" :data="uploadParams" :before-upload="beforeUpload" :on-preview="handlePictureCardPreview" :limit="1" :on-exceed="onlyoneUpload" :on-remove="removeUpload" :on-success="successUpload" :file-list="fileList" :accept="fileTypes">
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
dialogImageUrl: '',
dialogImageVisible: false,
uploadParams: {},
fileList: [],
fileTypes: '.jpg,.jpeg,.png,.gif,.bmp,.pdf,.JPG,.JPEG,.PBG,.GIF,.BMP'
beforeUpload () {
this.uploadParams.access_token = window.localStorage.getItem('TOKEN')
// 校验文件上传类型
let pic = this.$refs.proUpload.uploadFiles[0]
let type = pic.name.split('.')[1]
if (this.fileTypes.indexOf(type) === -1) {
this.$message.warning('请上传正确的图片格式!')
return false
}
},
onlyoneUpload () {
this.$message.warning('只允许上传一张图片,请删除前者后上传!')
},
removeUpload (file, fileList) {
this.entBox.businessLicense = null
},
successUpload (response, file, fileList) {
this.entBox.businessLicense = response.resData
},
handlePictureCardPreview (file) {
this.dialogImageUrl = file.url
this.dialogImageVisible = true
},
// 清除el-upload绑定图片
if (this.$refs.proUpload) this.$refs.proUpload.clearFiles()
this.fileList = []
// 仅查看时代码
this.justCheck = true
let picObj = {
url: 文件地址=后台文件下载接口+对应文件ID
}
this.fileList.push(picObj)
需求二、一起上传
录入信息和图片,一起调同一个接口提交。
代码如下:
<el-form :model="faultBox" :rules="rules" ref="faultBox" label-width="100px">
<el-row>
<el-form-item label="详细地址" prop="position">
<el-input v-model="faultBox.position"></el-input>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="故障图片" prop="fileIdList">
<label slot="label">故障图片 (请上传20M以内的图片)</label>
<el-upload ref="proUpload" :auto-upload="false" list-type="picture-card" :on-preview="handlePictureCardPreview" :accept="fileTypes">
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
</el-row>
</el-form>
<div slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</div>
<el-dialog :visible.sync="dialogImageVisible" width="100%">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
dialogImageUrl: '',
dialogImageVisible: false,
fileTypes: '.jpg,.jpeg,.png,.gif,.bmp,.pdf,.JPG,.JPEG,.PBG,.GIF,.BMP'
handlePictureCardPreview (file) {
this.dialogImageUrl = file.url
this.dialogImageVisible = true
},
submitForm () {
let self = this
// 校验文件上传类型 处理图片列表
let typeFlag = true
let formData = new FormData()
for (let i = 0; i < self.$refs.proUpload.uploadFiles.length; i++) {
let onePic = self.$refs.proUpload.uploadFiles[i]
let oneType = onePic.name.split('.')[1]
if (self.fileTypes.indexOf(oneType) === -1) {
typeFlag = false
break
}
formData.append('file', onePic.raw)
}
if (!typeFlag) {
self.$message.error('请上传正确的图片格式!')
return false
}
// 自定义表单验证
if (!self.entIp) {
self.$message.warning('当前设备无法上报故障!')
} else {
self.$refs.faultBox.validate((valid) => {
if (valid) {
self.dialogVisible = false // 防止别人一直点击提交
let params = {
position: self.faultBox.position
}
let url = self.$_apiUrl.submitFualt
self.$axiosFile(url, formData, params, self.saveFaultRes)
} else {
self.$message.error(self.$t('message.crud.rulesFailed'))
return false
}
})
}
},
// 上传文件请求
export const axiosFile = (url, formData, params, callback) => {
// 附加的参数以Blob的格式追加到formData中
formData.append('data', new Blob([JSON.stringify(params)], {
type: 'application/json'
}))
return axios.post(url, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(res => {
if (typeof callback === 'function') callFunction(callback, res)
})
.catch(res => {
})
}
附注说明
1、auto-upload
选择文件后是否开始自动调用上传接口,默认为true。
:auto-upload="false",不调用上传接口,浏览器读取文件暂存。
2、action
文件自动上传或手动提交(手动调用el-upload的submit方法,this.$refs.proUpload.submit())时调用该接口
注意,action就是一个接口路径不能是额外的方法,如需附带参数详见data属性,如需调用其他方法使用http-request。
3、data
上传时附带的额外参数,如果参数是动态变化的,比如获取token,可通过before-upload,在上传之前把参数设置好。
<el-upload ref="proUpload" :data="uploadParams" :before-upload="beforeUpload"></el-upload>
uploadParams: {},
beforeUpload () {
this.uploadParams.access_token = window.localStorage.getItem('TOKEN')
},
4、http-request
文件自动上传或手动提交(手动调用el-upload的submit方法,this.$refs.proUpload.submit())时,不再直接走action的接口,执行当前方法。
5、file-list
上传的文件列表,该属性是将文件手动绑定到el-upload上的。并不是打开文件或上传成功后自动修改该属性的,需要手动修改!!!
6、disabled
文件上传禁用,仅展示图片。
7、accept
接受上传的文件类型,我发现只是打开文件时初始会过滤掉那些类型,但是选择如果选择非上传类型的只要接口不限制仍然能上传成功,所以需要自行判断提示。
8、文件下载展示
8.1、调接口下载文件
let self = this
axios({
method: 'get',
url: `文件下载接口`,
params: `对应文件参数`,
responseType: 'blob'
})
.then(res => {
const blob = new Blob([res.data])
let picObj = {
url: window.URL.createObjectURL(blob)
}
self.fileList.push(picObj)
// self.picSrc = `文件下载接口` + `对应文件参数`
})
.catch(res => {
})
8.2、直接将文件路径及接口+参数赋值
<img src="`文件下载接口` + `对应文件参数`">
或
let picObj = {
url: 文件地址=后台文件下载接口+对应文件ID
}
this.fileList.push(picObj)