vue开发者必看!基于element实现文件上传功能的完整教程

前言

web 应用中,文件上传已经成为了一个必不可少的功能。本文将介绍如何使用 vueelement 实现简单而强大的文件上传功能,让你的 web 应用更加出色!


实现思路

其实基于 element 已经封装好的内容,通过 el-upload 组件的属性,实现上传的操作还是很易如拾芥的。我们只需要请求接口上传图片,上传成功后,将后台返回的 url 回显到页面即可。

传递参数

vue开发者必看!基于element实现文件上传功能的完整教程_第1张图片

返回数据

vue开发者必看!基于element实现文件上传功能的完整教程_第2张图片


用到的属性

属性 描述
accept 接受上传的文件类型(thumbnail-mode 模式下此参数无效)
action 必选参数,上传的地址
http-request 覆盖默认的上传行为,可以自定义上传的实现
show-file-list 是否显示已上传文件列表

实现效果


完整代码

<template>
  <div class="parentBox">
    <el-upload :accept="acceptAstrict" class="avatar-uploader" action="#" :http-request="uploadFiles" :show-file-list="false">
      <div class="iconBox">
        <i title="点击上传图片" v-if="!imgUrl" class="el-icon-plus avatar-uploader-icon"></i>
      </div>
    </el-upload>
    <el-image v-if="imgUrl" :src="imgUrl" :preview-src-list="[imgUrl]"></el-image>
    <div title="点击删除图片" v-if="imgUrl" class="gbtpBox" @click="imageRemove"><span>×</span></div>
  </div>
</template>
<script>
import { uploadFiles } from '@api/zjmj/zdqyjg'//引入的接口文件
export default {
    data() {
        return {
            acceptAstrict: '.jpg,.jpeg,.png,.JPG,.PNG', //文件上传限制
            imgUrl: '' //图片地址
        }
    },
    methods: {
        //上传图片
        uploadFiles(file) {
            // 调用文件大小校验方法
            if (this.beforeUpload(file.file)) {
                this.formData = new FormData()
                this.formData.append('file', file.file)
                // 请求接口
                uploadFiles(this.formData).then((res) => {
                    if (res.code == '10000') {
                        this.$message({
                            message: '上传成功',
                            type: 'success'
                        })
                        // 图片赋值
                        this.imgUrl = res.data.realPath
                    } else {
                        // 错误信息
                        this.$message({
                            message: res.msg,
                            type: 'error'
                        })
                    }
                })
            }
        },
        // 文件大小校验
        beforeUpload(file) {
            if (file.size > 10 * 1024 * 1024) {
                this.$message('文件过大,请上传小于10MB的文件〜')
                return false
            }
            return true
        },
        // 删除图片
        imageRemove() {
            this.imgUrl = ''
            this.$message({
                message: '删除图片成功',
                type: 'success'
            })
        }
    }
}
</script>
<style scoped>
.parentBox {
    padding: 20px;
}
.iconBox i {
    width: 100px;
    height: 100px;
    text-align: center;
    line-height: 100px;
    font-size: 20px;
    color: #8c939d;
    font-weight: bold;
    border: 1px #8c939d dashed;
    border-radius: 4px;
    background: rgb(251, 253, 255);
}
.iconBox i:hover {
    border: 1px rgb(64, 158, 255) dashed;
}
.el-image {
    width: 100px;
    height: 100px;
    border-radius: 4px;
    border: 1px solid rgb(192, 204, 218);
}
.gbtpBox {
    position: relative;
}
.gbtpBox span {
    position: absolute;
    top: -110px;
    left: 90px;
    cursor: pointer;
    font-size: 16px;
    border-radius: 50%;
    width: 16px;
    height: 16px;
    text-align: center;
    line-height: 16px;
    background: rgb(245, 108, 108);
    color: #fff;
}
.gbtpBox span:hover {
    background: rgb(247, 137, 137);
    color: #fff;
}
::v-deep .avatar-uploader {
    height: 0px;
}
</style>

上传多张

上面我们实现的只能上传一张图片,那如果需求是可上传多张图片,就需要下面这种方式。

用到的属性

属性 描述
multiple 是否支持多选文件
on-exceed 文件超出个数限制时的钩子
on-remove 文件列表移除文件时的钩子
limit 最大允许上传个数
before-upload 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
http-request 覆盖默认的上传行为,可以自定义上传的实现
list-type 文件列表的类型
on-preview 点击文件列表中已上传的文件时的钩子
:class=“{hideShow: hideUpload}” 当上传超过限制数量时,通过动态样式显隐上传图标

实现效果


完整代码

<template>
  <div class="parentBox">
    <el-upload :class="{hideShow: hideUpload}" :multiple="true" :on-exceed="onExceed" :on-remove="handleRemove" :limit="limit"
      :before-upload="beforeUpload" action="" :http-request="uploadFiles" list-type="picture-card" :on-preview="handlePictureCardPreview">
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="imgUrl">
    </el-dialog>
  </div>
</template>
<script>
import { uploadFiles } from "@api/records";
export default {
  data() {
    return {
      limit: 3, //最大上传数量
      dialogVisible: false, //预览图片框
      imgUrl: "", // 图片地址
      fileList: [], //图片数组
    };
  },
  // 上传超过限制后隐藏上传图标
  computed: {
    hideUpload() {
      console.log(this.fileList.length);
      console.log(this.limit);
      return this.fileList.length >= this.limit;
    },
  },
  methods: {
    //上传图片方法
    uploadFiles(file) {
      let formData = new FormData();
      formData.append("file", file.file);
      // 请求接口
      uploadFiles(formData).then((res) => {
        if (res.code == "10000") {
          this.fileList.push({
            uid: file.file.uid,
            url: res.data,
          });
          console.log(this.fileList);
          this.$message({
            message: res.msg,
            type: "success",
          });
        } else {
          // 错误信息
          this.$message({
            message: res.msg,
            type: "error",
          });
        }
      });
    },
    // 预览当前图片
    handlePictureCardPreview(file) {
      this.imgUrl = file.url;
      this.dialogVisible = true;
    },
    // 删除当前图片
    handleRemove(file, fileList) {
      let index = this.fileList.findIndex((item) => {
        return item.uid === file.uid;
      });
      this.fileList.splice(index, 1);
    },
    // 当前上传图片大小格式校验
    beforeUpload(file) {
      let fileArr = file.name.split(".");
      let suffix = fileArr[fileArr.length - 1];
      if (!/(jpg|jpeg|png|JPG|PNG|gif|GIF)/i.test(suffix)) {
        this.$message("图片格式不正确");
        return false;
      }
      if (file.size > 10 * 1024 * 1024) {
        this.$message.warning("图片大小不能超过 10MB!");
        return false;
      }
      return true;
    },
    // 文件上传超出个数
    onExceed(files, fileList) {
      this.$message(`最多上传 ${this.limit} 张图片`);
    },
  },
};
</script>
<style scoped>
::v-deep .el-upload--picture-card {
  width: 100px;
  height: 100px;
  line-height: 109px;
}
::v-deep .el-upload-list--picture-card .el-upload-list__item {
  width: 100px;
  height: 100px;
}
/* 上传超过限制后隐藏上传图标 */
::v-deep .hideShow .el-upload--picture-card {
  display: none;
}
</style>

多次调用

这种情况多用于一个表单中有很多个上传的组件,在上传和删除都调用接口(以下案例上传成功后返回的信息就是删除所需要的参数),最后提交时就不用携带上传的数据了。

完整源码

<template>
  <div>
    <el-upload :file-list="xszzp" :before-remove="setDataBeforeRemove" :multiple="true" :on-exceed="onExceed" :on-remove="xszzpRemove"
      :limit="5" :before-upload="beforeUpload" action="#" :http-request="xszzpFiles" list-type="picture-card"
      :on-preview="handlePictureCardPreview">
      <i class="el-icon-plus">i>
    el-upload>
  div>
template>
<script>
import { uploads, deleteFiles } from "@/api/inspection/index";
export default {
  data() {
    return {
      imgMap: new Map(),
      xszzp: [], //存放图片的数组
    };
  },
  mounted() {
    // 模拟回显
    this.xszzp = [
      {
        checklistId: 32,
        url: "http://119.253.35.74:39000/defaults/20230320/4CD40BABF4B14231AF07E58DC78301C8.png",
        id: 202,
        moduleId: 54,
        name: "20230320/4CD40BABF4B14231AF07E58DC78301C8.png",
        realPath: "20230320/4CD40BABF4B14231AF07E58DC78301C8.png",
        type: 1,
      },
      {
        checklistId: 12,
        url: "http://119.253.35.74:39000/defaults/20230320/2B1D3E48A01A4BD8B0FB97FE0047A01D.png",
        id: 203,
        moduleId: 43,
        name: "20230320/2B1D3E48A01A4BD8B0FB97FE0047A01D.png",
        realPath: "20230320/2B1D3E48A01A4BD8B0FB97FE0047A01D.png",
        type: 1,
      },
    ];
    //接口回显
    // taskCarView() {
    //   taskCarView().then((res) => {
    //     if (res.code == "10000") {
    //       this.ruleForm = res.data;
    //       // 行驶证回显
    //       if (res.data.xszImg) {
    //         res.data.xszImg.forEach((item) => {
    //           this.xszzp.push({
    //             checklistId: item.checklistId,
    //             url: item.enclosure,
    //             id: item.id,
    //             moduleId: item.moduleId,
    //             name: item.realPath,
    //             realPath: item.realPath,
    //             type: item.type,
    //           });
    //         });
    //       }
    //     }
    //   });
    // },
  },
  methods: {
    // 上传图片
    xszzpFiles(file) {
      // uid 是唯一的
      let uid = file.file.uid;
      let formData = new FormData();
      formData.append("file", file.file);
      uploads(formData).then((res) => {
        if (res.code == "10000") {
          this.imgMap.set(uid, res.data);
          this.$message({
            message: res.msg,
            type: "success",
          });
        }
      });
    },
    // 删除行驶证照片
    xszzpRemove(file, flist) {
      let uid = file.uid;
      let targetImg = this.imgMap.get(uid);
      // 删除所需的参数
      let params = {
        id: targetImg.id,
        filePath: targetImg.realPath,
      };
      // 请求接口
      deleteFiles(params).then((res) => {
        if (res.code == "10000") {
          this.$message({
            message: res.msg,
            type: "success",
          });
        }
      });
    },
    //对于回显的数据删除之前,先获取图片数据存储到imgMap,用来给接口传id和url(公共)
    setDataBeforeRemove(file, fileList) {
      let uid = file.uid;
      if (file.status == "success") {
        //此状态为回显的数据
        if (!this.imgMap.hasOwnProperty(uid)) {
          this.imgMap.set(uid, file);
        }
      }
    },
    // 当前上传图片大小格式校验
    beforeUpload(file) {
      let fileArr = file.name.split(".");
      let suffix = fileArr[fileArr.length - 1];
      if (!/(jpg|jpeg|png|JPG|PNG|gif|GIF)/i.test(suffix)) {
        this.$message("图片格式不正确");
        return false;
      }
      if (file.size > 10 * 1024 * 1024) {
        this.$message.warning("图片大小不能超过 10MB!");
        return false;
      }
      return true;
    },
    // 预览图片
    handlePictureCardPreview(file) {
      this.imgDialog.dialogRow = file.url;
      this.imgDialog.dialogLsattr = true;
    },
    // 文件上传超出个数
    onExceed() {
      this.$message(`最多上传 5 张图片`);
    },
  },
};
script>

相关推荐

⭐ element表格上传图片必看:如何避免全行上传?
⭐ 让图片上传变得更简单:vue和vant的完美融合
⭐ 小程序开发攻略:如何优雅地实现图片上传?

你可能感兴趣的:(element,前端,vue)