https://element-plus.org/zh-CN/component/upload.html
本页大部分来自网络
开发中经常也会遇到附件的上传和回显,最方便的就是我们封装一个公共组件在页面中引用
在src里面新建一个文件夹
<template>
<el-upload class="upload-demo"
multiple
:limit="limit"
:accept="accept"
:headers="headers"
:file-list="fileList"
:action="uploadImgUrl"
:on-exceed="handleExceed"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="beforeUpload"
:on-error="handleUploadError">
<!-- :on-preview="handlePreview" -->
<el-button size="small"
type="primary">点击上传</el-button>
<div slot="tip"
class="el-upload__tip"
style="color:#909399">
支持上传{{ accept === "*" ? "所有" : accept }}文件,且不超过20MB,附件名称不能超过50字
</div>
</el-upload>
</template>
<script>
import { getToken } from '@/utils/auth'
export default {
components: {},
props: {
value: {
type: String,
default: null
},
accept: {
type: String,
default: '*'
},
limit: {
type: Number,
default: 1
}
},
data () {
return {
uploadImgUrl: process.env.VUE_APP_BASE_API + '/common/upload', // 上传的图片服务器地址
headers: {
Authorization: 'Bearer ' + getToken()
},
fileList: [],
returnData: []
}
},
watch: {},
mounted () {
this.value === null && this.value === '' ? (this.fileList = []) : this.getFileList()
},
methods: {
getFileList () {
if (this.value !== null && this.value !== '') {
const accessory = JSON.parse(this.value)
this.fileList = []
accessory.map(val => {
this.fileList.push({
name: val.name,
// 编辑修改
// response: {
// fileName: val.url
// },
response: {
data: {
fileName: val.url
}
}
})
})
}
},
// 删除上传文件后
handleRemove (file, fileList) {
this.getReturnData(fileList)
},
// 上传前------------文件大小和格式校验
beforeUpload (file) {
if (this.accept !== '*') {
var fileType = file.name.substring(file.name.lastIndexOf('.') + 1)
const accept = this.accept.split(',')
if (accept.indexOf('.' + fileType) < 0) {
this.$message.warning('请选择正确的文件格式')
return false
}
}
const isLt50M = file.size / 1024 / 1024 < 20
if (!isLt50M) {
this.$message.warning('上传附件大小不能超过 20MB!')
return false
}
return true
},
// 附件上传成功后的钩子
handleSuccess (response, file, fileList) {
if (response.code === 200) {
this.getReturnData(fileList)
} else {
this.$message.error(response.msg)
this.fileList=[]
}
},
handleUploadError () {
this.$message({
type: 'error',
message: '上传失败'
})
},
// 获取附件信息后进行返回处理
getReturnData (fileList) {
this.returnData = []
console.log(fileList)
fileList.map(val => {
this.returnData.push({
name: val.name,
url: val.response.data.fileName
})
})
this.$emit('input', JSON.stringify(this.returnData))
},
// 点击上传文件的钩子
handlePreview (file) {
var a = document.createElement('a', '_bank')
var event = new MouseEvent('click')
a.download = file.name
a.href = file.response.url
a.dispatchEvent(event)
},
// 文件超出个数限制时的钩子
handleExceed (files, fileList) {
this.$message.warning(`当前限制只能上传 ` + this.limit + ` 个文件`)
},
// 删除文件之前的钩子,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除。
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}?`)
}
}
}
</script>
代码中这个import { getToken } from ‘@/utils/auth’,其实是获取的存在Cookies里面的token的值,大家可以根据自己项目情况进行修改使用
在页面中直接引入使用就可以了:
和上传一样同样新建一个文件夹
<template>
<div class="upload-detail">
<div class="detail"
style="line-height:20px"
v-if="accessory === '[]' || accessory === null">无</div>
<div v-else>
<template v-for="(val,key) in upload.fileList">
<el-link :key="key"
class="detail"
:underline="false"
@click="handlePreview(val)">{{val.name}}
<span class="icon-emad- icon-emad-xiazai"> 下载</span>
</el-link>
</template>
</div>
</div>
</template>
<script>
export default {
data () {
return {
upload: {
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/common/upload",
// 上传的文件列表
fileList: []
}
}
},
props: {
accessory: {
type: String,
default: '[]'
}
},
created () {
this.getInfo(this.accessory)
},
methods: {
getInfo (accessory) {
this.upload.fileList = []
if (accessory !== '[]' || accessory !== null) {
let list = JSON.parse(accessory)
list.map(val => {
this.upload.fileList.push({
name: val.name,
url:process.env.VUE_APP_BASE_API + val.url
})
})
}
},
// 点击上传----------------文件下载
handlePreview (file) {
var a = document.createElement('a');
var event = new MouseEvent('click');
a.download = file.name;
a.href = file.url;
a.dispatchEvent(event);
}
}
};
</script>
<style lang="scss" scoped>
::v-deep .el-upload-list {
height: auto;
overflow: hidden;
}
.detail {
line-height: 20px;
display: block;
.icon-emad- {
color: rgba(98, 173, 255, 1);
}
}
</style>
el-upload多文件一次性上传的实现
项目需求是多个文件上传,在一次请求中完成,而ElementUI的上传组件是每个文件发一次上传请求,因此我们借助FormData的格式向后台传文件组
<div class="upload-file">
<el-upload
accept=".xlsx"
ref="upload"
multiple
:limit="5"
action="http://xxx.xxx.xxx/personality/uploadExcel"
:on-preview="handlePreview"
:on-change="handleChange"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:file-list="fileList"
:http-request="uploadFile"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<el-button style="margin-left: 133px;" size="small" type="success" @click="submitUpload">上传到服务器
</el-button>
<div slot="tip" class="el-upload__tip">只能上传xlsx文件,且不超过100m</div>
</el-upload>
</div>
修改:auto-upload="false"属性为false,阻止组件的自动上传
:http-request="uploadFile"覆盖上传事件
@click=“submitUpload”,给上传按钮绑定事件
data() {
return {
fileData: '', // 文件上传数据(多文件合一)
fileList: [], // upload多文件数组
uploadData: {
fieldData: {
id: '', // 机构id,
}
},
}
}
methods:{
// 上传文件
uploadFile(file) {
this.fileData.append('files', file.file); // append增加数据
},
// 上传到服务器
submitUpload() {
let fieldData = this.uploadData.fieldData; // 缓存,注意,fieldData不要与fileData看混
if (fieldData.id === '') {
this.$message({
message: '请选择上传机构',
type: 'warning'
})
} else if (this.fileList.length === 0) {
this.$message({
message: '请先选择文件',
type: 'warning'
})
} else {
const isLt100M = this.fileList.every(file => file.size / 1024 / 1024 < 100);
if (!isLt100M) {
this.$message.error('请检查,上传文件大小不能超过100MB!');
} else {
this.fileData = new FormData(); // new formData对象
this.$refs.upload.submit(); // 提交调用uploadFile函数
this.fileData.append('pathId', fieldData.id); // 添加机构id
this.fileData.append('loginToken', this.loginToken); // 添加token
post(this.baseUrlData.url_02 + ":8090/personality/uploadExcel", this.fileData).then((response) => {
if (response.data.code === 0) {
this.$message({
message: "上传成功",
type: 'success'
});
this.fileList = [];
} else {
this.$message({
message: response.data.desc,
type: 'error'
})
}
});
}
}
},
//移除
handleRemove(file, fileList) {
this.fileList = fileList;
// return this.$confirm(`确定移除 ${ file.name }?`);
},
// 选取文件超过数量提示
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
//监控上传文件列表
handleChange(file, fileList) {
let existFile = fileList.slice(0, fileList.length - 1).find(f => f.name === file.name);
if (existFile) {
this.$message.error('当前文件已经存在!');
fileList.pop();
}
this.fileList = fileList;
},
}
此时就达到上传4个文件只发送了一个xhr请求了
el-upload http-request使用
1、http-request:覆盖默认的上传行为,可以自定义上传的实现
2、不需要给action关联上传的地址,但是action这个属性必须写
3、在http-request自定义上传事件中将上传文件保存到一个数组中
4、 接口使用formData表单数据格式传参, 将上传的文件和其他参数一起传给接口,使用的方法是new FormData()
4、如果是单文件上传并携带参数,可以直接在http-request自定义事件中调用后端接口