补充1:图片太大时候上传失败,报错,直接没走到上传接口,要添加headers属性!
项目在上传文件时,后端请求没有返回结果,但是在谷歌浏览器控制台会报错net::ERR_CONNECTION_RESET
重新设置upload标签的请求头是最重要的,因为element-ui组件库中的upload这个组件上传图片并没有使用我们自己在项目中定义的Axios请求,而是使用了组件库中自己封装的。所以需要在upload中重新设置符合项目需求的请求头。
例如:在vue项目项目开发中,登录注册一个应用,进行后续相关网页访问都是需要携带token,才能有权限继续访问的。所以在upload这个组建中也需要携带这个特定的请求头。upload中的headers就是用来重新设置请求头的。
:headers="headerOdj" // 重要!!
<el-upload
:headers="headerOdj" // 重要!!
ref="upload"
:action="adminUrl"
list-type="picture-card"
:before-upload="beforeAvatarUpload"
:on-success="handlePictureCardPreview"
:on-remove="handleRemove"
:file-list="imgList"
>
<i slot="default" class="el-icon-plus"></i>
</el-upload>
// 放data()中
headerOdj: {
Authorization: window.sessionStorage.getItem('token')
},
补充2:图片上传时候一下会走2次图片上传接口且上传2张一样的图片,因为 属性 :action="adminUrl" 定义有问题,不能使用注释的方式。
data(){
return{
// adminUrl: this.GLOBAL.imgUrl + "/system/entranceguard/uploadImg", //后台请求地址,
adminUrl: this.GLOBAL.imgUrl, //后台请求地址,
}
}
修改前:2次请求都是成功的,会上传2张一样图片
修改后:就第二次请求走通,上传一张图片
-----------------------------------------------------------------------------------------------------------------
一、多张图片
注意:style需取消el-upload组件中图片动画样式,不然显示会异常
action 图片上传后台请求地址(必填)
list-type="picture-card" 照片墙显示
before-upload 图片上传前
on-success 图片上传成功时候
on-remove 图片删除时候
file-list 组件默认显示图片的数组,有具体格式[{url:"xxxxx图片地址" }]
:limit="9" 限制上传的图片张数为9
html和数据定义部分:
<el-form-item>
<!-- -----------图片上传----------------- -->
<el-upload
ref="upload"
:action="adminUrl"
list-type="picture-card"
:before-upload="beforeAvatarUpload"
:on-success="handlePictureCardPreview"
:on-remove="handleRemove"
:file-list="imgList"
>
<i slot="default" class="el-icon-plus"></i>
<div class="el-upload__tip" slot="tip" style="font-weight: bold">
建议尺寸大小为192*128,大小不超过2M
</div>
</el-upload>
</el-form-item>
import { uploadImgTbt } from "@/api/system/tbt"; // 上传图片接口
data() {
return {
// 组件el-upload组件 file-list属性 默认显示的图片组数,格式如下
imgList: [
// {
// url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
// },
// {
// url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
// },
],
adminUrl: this.GLOBAL.imgUrl , //图片上传后台地址,
form:{
contextImg:[] // 实际表单要提交的 需通过图片接口转换过 图片列表信息
}
};
},
函数方法部分:
methods: {
// 上传图片文件前
beforeAvatarUpload(file) {
const isJPG = file.type === "image/jpeg" || "image/png";
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error("上传头像图片只能是 JPG/PNG 格式!");
}
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!");
}
return isJPG && isLt2M;
},
// 图片上传--移除
handleRemove(file, fileList) {
// console.log("##file", file.url);
// 1.把删除的图片url地址 去掉http://192.168.xxx.xx:8080 头部
// 2.去实际上传的 form.contextImg 去掉这条数据
const str = file.url;
let delStr = str.replace(this.GLOBAL.imgUrl, "");
// console.log("delStr=>", delStr);
for (let i = 0; i < this.form.contextImg.length; i++) {
if (this.form.contextImg[i] == delStr) {
this.form.contextImg.splice(i, 1);
}
}
// console.log("删除时候form.contextImg", this.form.contextImg);
},
//-图片上传成功时候数组
handlePictureCardPreview(response, file, fileList) {
if (file != null) {
// 接口上传 需要formData 文件类型
let formData = new FormData();
// "uploadImage" 这个字段需要看后端需提供详细
formData.append("uploadImage", file.raw);
uploadImgTbt(formData).then((response) => {
// 如果form没有这个 contextImg属性 那么就加一个
if (!this.form.contextImg) {
this.form.contextImg = [];
}
// console.log("###form.contextImg", this.form.contextImg);
// 把上传返回的数据拼接到图像数组中
this.form.contextImg.push(response.msg);
// console.log("###form.contextImg", this.form.contextImg);
});
}
},
// 表单重置
reset() {
this.imgList = [];
this.form = {
id: null,
title: null,
context: null,
initTime: null,
};
this.resetForm("form");
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.title = "添加xxx";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getTbt(id).then((response) => {
this.form = response.data;
this.title = "修改xxx";
// console.log("###form", this.form);
// 1.把原来form.contextImg JSON数组 转换回数组形式 (提交时候再转回Json格式)
// 2.把el-upload 中的file-list要回显的图片拼接完形式用 imgList存储
var jsonArray2 = eval(this.form.contextImg);
this.form.contextImg = jsonArray2;
this.imgList = [];
// console.log("form.contextImg###", this.form.contextImg);
for (let i = 0; i < this.form.contextImg.length; i++) {
const obj = {};
obj.url = this.GLOBAL.imgUrl + this.form.contextImg[i];
this.imgList.push(obj);
}
});
},
}
axios请求文件:
// 上传图片信息 要用file类型传
export function uploadImgTbt(file) {
return request({
url: '/xxx/xxx/uploadImg',
method: 'post',
data: file
})
}
定义全局 this.GLOBAL.imgUrl 路径:
1.创建Global.vue的文件
<script>
const imgUrl = 'http://192.168.xxx.xx:8081'; //请求地址
export default {
imgUrl,
}
</script>
2.main.js文件中引入
// 全局定义服务器地址链接
import global from '@/views/xxx/xxx/Global' // 相对路径
Vue.prototype.GLOBAL = global;
style样式文件:
<style scoped>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
/* 去掉动画,不然会影响图片显示 */
::v-deep .el-upload-list__item {
transition: none !important;
-webkit-transition: nonne !important;
}
::v-deep .el-upload-list__item-name {
transition: none !important;
-webkit-transition: nonne !important;
}
</style>
二、单张图片
添加单张人脸信息,点击图片替换人脸,没有删除功能
list-type="picture-card" 照片墙格式
:show-file-list="false" 不允许多张图片显示,只一张
img标签 :src="imageUrl" 默认显示图片 因为是单图,字符串就行,v-if控制是新增还是修改
html和数据定义部分:
<el-form-item label="人脸信息" prop="faceImg">
<el-form-item>
<!-- -----------图片上传- 单张图片上传---------------- -->
<el-upload
class="avatar-uploader"
list-type="picture-card"
:action="adminUrl"
:show-file-list="false"
:before-upload="beforeAvatarUpload"
:on-success="handlePictureCardPreview"
:on-remove="handleRemove"
>
<img
v-if="imageUrl"
:src="imageUrl"
title="点击重新上传图片"
class="avatar"
/>
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
<!-- <div
v-if="imageUrl"
class="el-upload__tip"
slot="tip"
style="font-weight: bold"
>
点击重新上传图片
</div> -->
</el-upload>
</el-form-item>
</el-form-item>
import { uploadImgEntranceguard } from "@/api/system/entranceguard"; // 图片上传接口
data() {
return {
imageUrl: "", // 组件el-upload组件单张图片显示 imageUrl属性 默认显示的图片
adminUrl: this.GLOBAL.imgUrl, //后台请求地址,
// 表单参数
form: {
faceImg:"", // 实际提交表单要的转换过的图片信息
},
};
},
函数方法部分:
methods: {
// 上传图片文件前
beforeAvatarUpload(file) {
const isJPG = file.type === "image/jpeg" || "image/png";
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error("上传头像图片只能是 JPG/PNG 格式!");
}
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!");
}
return isJPG && isLt2M;
},
// 图片上传--移除
handleRemove(file, fileList) {
// console.log("##file", file);
// 一张图的话直接清空form.faceImg的数据
this.form.faceImg = "";
// console.log("删除时候form.faceImg", this.form.faceImg);
},
//-图片上传成功时候数组
handlePictureCardPreview(response, file, fileList) {
if (file != null) {
// 接口上传 需要formData 文件类型
let formData = new FormData();
// "uploadImage" 这个字段需要看后端需提供详细
formData.append("uploadImage", file.raw);
uploadImgEntranceguard(formData).then((response) => {
// console.log("####", response);
// 如果form没有这个 faceImg属性 那么就加一个
if (!this.form.faceImg) {
this.form.faceImg = "";
}
// console.log("###form.faceImg", this.form.faceImg);
// 把上传返回的数据拼接到图像数组中
this.form.faceImg = response.msg;
// 把上传组件默认显示图片赋值
this.imageUrl = this.GLOBAL.imgUrl + response.msg;
// console.log("###form.faceImg", this.form.faceImg);
});
}
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加xxx";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getEntranceguard(id).then((response) => {
this.form = response.data;
// console.log("form###", this.form);
if (this.form.faceImg) {
// 默认显示图片
this.imageUrl = this.GLOBAL.imgUrl + this.form.faceImg;
// console.log(this.imageUrl);
}
this.open = true;
this.title = "修改xxx";
});
},
}
axios请求文件:
// 上传图片信息 文件类型需file类型
export function uploadImgEntranceguard(file) {
return request({
url: '/xxx/xxx/uploadImg',
method: 'post',
data: file
})
}
css样式文件:
<style scoped>
::v-deep .el-upload--picture-card {
width: 176px;
height: 178px;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
/* 单人 */
.avatar {
width: 170px;
height: 170px;
display: block;
margin-left: 2px;
margin-top: 2px;
}
/* 去掉动画 */
::v-deep .el-upload-list__item {
transition: none !important;
-webkit-transition: nonne !important;
}
::v-deep .el-upload-list__item-name {
transition: none !important;
-webkit-transition: nonne !important;
}
</style>