el-upload component uploads leaflets/multiple pictures

Supplement 1: When the image is too large, the upload fails and an error is reported. The upload interface is not reached directly. You need to add the headers attribute!

 When the project uploads files, the backend request does not return a result, but the error net::ERR_CONNECTION_RESET is reported in the Google Chrome console.

Resetting the request header of the upload tag is the most important , because the upload component in the element-ui component library does not use the Axios request we defined in the project to upload images, but uses its own encapsulation in the component library. Therefore, you need to reset the request header in upload to meet the project requirements.

For example: In the development of the Vue project, logging in to register an application and subsequent access to related web pages require a token to have permission to continue accessing. Therefore, this specific request header also needs to be carried in the upload component. The headers in upload are used to reset the request headers.

:headers="headerOdj" // Important! !

          <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')
            },

Supplement 2: When uploading images, you will go through the image upload interface twice at once and upload 2 identical images. Because there is a problem with the definition of the attribute: action="adminUrl", the comment method cannot be used.

      data(){
          return{
            // adminUrl: this.GLOBAL.imgUrl + "/system/entranceguard/uploadImg", //后台请求地址,
              adminUrl: this.GLOBAL.imgUrl, //后台请求地址,
        }
            
        }

Before modification: Both requests were successful and 2 identical pictures were uploaded.

After modification: For the second request to go through, upload a picture

-----------------------------------------------------------------------------------------------------------------

1. Multiple pictures

Note: style needs to cancel the image animation style in the el-upload component, otherwise the display will be abnormal.

action image upload background request address (required)

list-type="picture-card" photo wall display

before-upload before the image is uploaded

on-success When the image is uploaded successfully

on-remove when the picture is deleted

The file-list component displays an array of images by default, with a specific format [{url: "xxxxx image address" }]

:limit="9" limits the number of uploaded images to 9

html and data definition part:

        <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:[] // 实际表单要提交的 需通过图片接口转换过 图片列表信息
      }
    };
  },

Function method part: 

 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 request file:

// 上传图片信息 要用file类型传
export function uploadImgTbt(file) {
  return request({
    url: '/xxx/xxx/uploadImg',
    method: 'post',
    data: file
  })
}

Define the global this.GLOBAL.imgUrl path:

1. Create the Global.vue file

<script>

    const imgUrl = 'http://192.168.xxx.xx:8081'; //请求地址

    export default {

        imgUrl,

    }

</script>

2.Introduced in the main.js file

// 全局定义服务器地址链接
import global from '@/views/xxx/xxx/Global'   // 相对路径
Vue.prototype.GLOBAL = global;

 style style file:

<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. Single picture

 Add a single face information, click on the picture to replace the face, there is no deletion function

list-type="picture-card" photo wall format

:show-file-list="false" does not allow multiple pictures to be displayed, only one

img tag: src="imageUrl" displays the image by default because it is a single image, just a string , v-if controls whether to add or modify

html and data definition part:

<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:"", // 实际提交表单要的转换过的图片信息
      },
    };
  },

Function method part:

  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 request file:

// 上传图片信息 文件类型需file类型
export function uploadImgEntranceguard(file) {
  return request({
    url: '/xxx/xxx/uploadImg',
    method: 'post',
    data: file
  })
}

css style file:

<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>

Guess you like

Origin blog.csdn.net/m0_61601708/article/details/129950582