最近在用vue-elementui-admin开发中,使用到了在form中上传附件并根据不同情况校验,所以封装了这样一个包含上传、提示、不同情况加校验、修改请求头)这样的一个uoload组件,在这里记录一下,也希望能帮助到您,话不多说,上代码
首先是子组件
<template>
<div>
<el-upload
:action="VUE_APP_UPLOAD_URL"
ref="uploadMultiple"
name="picStrem"
:list-type="listType"
:must-verify="mustVerify"
:data="param"
:file-list="fileList"
:limit="limit"
:headers="myHeaders"
:on-exceed="handleUploadExceed"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:before-upload="upLoadMethods"
:on-success="handleSuccess"
:on-error="handleError"
>
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt />
</el-dialog>
</div>
</template>
<script>
import axios from 'axios'
import { uploadFile, deleteFile } from '@/api/api' //接口
import eventVue from '@/views/onlineInspection/center.js' //广播传值过程暴露的空实例
export default {
name: 'MultiUpload',
props: {
value: {
type: Array,
default: () => []
},
limit: {
type: Number,
default: 4
},
listType: {
type: String,
default: 'text'
},
fileType: {
type: String
},
mustVerify: {
type: Boolean,
default: false
}
},
data() {
return {
VUE_APP_UPLOAD_URL: '您的上传地址',
dialogImageUrl: '',
dialogVisible: false,
myHeaders: {
'AccessToken': this.getToken() //这里重新定义了请求头
},
param: {
//这里定义您的附件上传的入参数据
}
}
},
created: function () {
this.idChangeReceive()
},
mounted() {
this.VUE_APP_UPLOAD_URL = '也可以作为变量动态获取'
},
computed: {
fileList() {
return this.value.map(url => ({ url }))
}
},
methods: {
idChangeReceive() {
const _this = this
eventVue.$on('workPlanIdChange', (val) => {
_this.param.workPlanId = val
})
eventVue.$on('orgIdChange', (val) => {
_this.param.orgId = val
})
},
handleUploadExceed() {
this.$message.error(`最多上传${this.limit}张图片`)
},
upLoadMethods(file) {
this.param.FileType = this.fileType
this.param.fileNameDisplay = file.name
},
handleSuccess(res, file) {
const { filePath } = res.data
this.$set(this.fileList, 0, file)
this.fileList.splice(1)
this.dialogImageUrl = filePath //此步骤未上传成功展示缩略图
this.mustVerify && this.$emit('verifyAdd', [this.fileType + 'Length', this.fileList.length]) //这里的this.$parent.prop获取的是父组件父节点的校验规则名,删除同理
this.$message({
message: '恭喜你,附件上传成功!',
type: 'success'
})
},
handleError(err, file, fileList) {
_this.$message.error('附件上传失败,请重试!')
},
handleRemove(file, fileList) {
const _this = this
deleteFile({ '您的对象参数' }).then(response => {
_this.fileList.splice(_this.fileList.indexOf(fileList), 1)
_this.mustVerify && _this.$emit('verifyRemove', [this.fileType + 'Length', this.fileList.length])
_this.$message({
message: '附件删除成功!',
type: 'warning'
})
}).catch(error => {
_this.$message.error('附件删除失败,请重试!')
})
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
getToken() { //这里在获取cooki里token,可修改为localstorage和sessionstorage,用法类似
var name = 'accessToken' + '='
var arr = document.cookie.split(';')
for (let i = 0; i < arr.length; i++) {
var item = arr[i].trim()
if (item.indexOf(name) === 0) {
return item.substring(name.length, item.length)
}
}
}
}
}
父组件
<el-form-item label="上传身份证" prop="BES1Length">
<multi-upload
:file-list="uploadFileList.BES1fileList"
:list-type="'picture'"
:file-type="'BES1'"
:must-verify="true"
:limit="1"
@verifyAdd="verifyAddElement"
@verifyRemove="verifyRemoveElement"
></multi-upload>
</el-form-item>
<el-form-item label="上传授权委托书">
<multi-upload
:file-list="uploadFileList.BES2fileList"
:list-type="'picture'"
:file-type="'BES2'"
:limit="1"
></multi-upload>
</el-form-item>
//父组件的校验规则就不在这重复了,可以去elementui官网看一下,很简单
//这两个方法主要用于校验个人身份证的必填,原理是子组件监听父组件事件
verifyAddElement(fileArr) {
this.$set(this.step2Form, fileArr[0], fileArr[1])
this.$refs[this.step2activeForm].clearValidate(fileArr[0])
},
verifyRemoveElement(fileArr) {
this.$set(this.step2Form, fileArr[0], fileArr[1])
this.$refs[this.step2activeForm].validate(fileArr[0])
},
因为我所做的业务这里涉及到的校验有表单form和table两种,但又不想在去单独写组件,所以这里存储文件信息是单独的一个对象,校验是在另一个form对象里,成功则在存储附件的数组里添加文件file,同时校验数组对应Length加1,用这个值在提交的时候去校验
个人感觉还能再精简一些,只是工作繁重,没有时间去整理,之后如果有更高效的代码,会准时更新
这也算是个人封装的比较成熟的一个组件,在此也保存一下