補足 1: 画像が大きすぎるとアップロードに失敗し、エラーが報告されます。アップロード インターフェイスに直接到達できないため、headers 属性を追加する必要があります。
プロジェクトがファイルをアップロードすると、バックエンド リクエストは結果を返しませんが、Google Chrome コンソールにエラー net::ERR_CONNECTION_RESET が報告されます。
アップロード タグのリクエスト ヘッダーをリセットすることが最も重要です。要素 UI コンポーネント ライブラリのアップロード コンポーネントは、画像をアップロードするためにプロジェクトで定義した Axios リクエストを使用せず、コンポーネント ライブラリ内の独自のカプセル化を使用するためです。したがって、プロジェクトの要件を満たすには、アップロード時にリクエスト ヘッダーをリセットする必要があります。
例: Vue プロジェクトの開発では、ログインしてアプリケーションを登録し、その後関連する Web ページにアクセスするには、アクセスを継続するためのアクセス許可を持つトークンが必要です。したがって、この特定のリクエスト ヘッダーもアップロード コンポーネントに含める必要があります。アップロードのヘッダーは、リクエスト ヘッダーをリセットするために使用されます。
: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 番目のリクエストを完了するには、写真をアップロードします。
-------------------------------------------------- -------------------------------------------------- -------------
1. 複数の写真
注: style は el-upload コンポーネントの画像アニメーション スタイルをキャンセルする必要があります。キャンセルしないと表示が異常になります。
アクション画像アップロード背景リクエストアドレス (必須)
list-type="picture-card" フォトウォールディスプレイ
before-upload 画像がアップロードされる前
on-success 画像のアップロードが成功した場合
写真が削除されたときの削除時
file-list コンポーネントは、デフォルトで特定の形式 [{url: "xxxxx image address" }] で画像の配列を表示します。
: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 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>
2. 1枚の写真
単一の顔情報を追加します。写真をクリックして顔を置き換えます。削除機能はありません。
list-type="picture-card" フォトウォール形式
:show-file-list="false" では、複数の画像を表示することはできません。1 つの画像のみを表示できます。
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: 178px;
height: 178px;
display: block;
margin-left: -1px;
margin-top: -1px;
}
/* 去掉动画 */
::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>