【vue2+element-ui】el-upload封装多图上传组件

halo小伙伴们,在开发表单中会有遇到需要多图上传,可动态限制上传的图片数量、大小,支持删除、显示提示语的需求。

在这小编带来一个小编自封装用了很久的多图上传组件,话不多说上代码。

首先创建一个如:XUploadImgList.vue的文件,编写如下:

html 复制代码
<template>
  <div>
    <el-upload
      ref="upload"
      :action="uploadUrl"
      list-type="picture-card"
      :auto-upload="true"
      :headers="headerObj"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-success="successUpload"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :limit="limit"
      accept=".jpg, .jpeg, .png"
    >
      <i slot="default" class="el-icon-plus" />
      <div v-if="showText" slot="tip" class="el-upload__tip">支持上传jpg/png格式图片,单个图片不能超过{{ maxSize }}M,最多上传{{ limit }}张<span v-if="suggestedSize">,建议尺寸: {{ suggestedSize }}</span></div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible" append-to-body>
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth'
import api, { getUploadUrlByImage} from "@/api/pagecreator/onlinegrid";

export default {
  name: "XUploadList",
  props:{
    //文件大小限制
    maxSize:{
      default: 2
    },
    //文件数限制
    limit:{
      default: 1
    },
    // 显示提示文本?
    showText:{
      default: true
    },
    value:{
      default: null,
      type:String
    },
    //建议尺寸
    suggestedSize:{
      default:''
    }
  },
  computed:{
    // 获取公共封装的请求地址
    uploadUrl: {
      get() {
        return getUploadUrlByImage()
      }
    }
  },
  data(){
    return{
      dialogImageUrl:'',
      dialogVisible:false,
      fileList: [],
      disabled: false,
      // 设置请求头-看后端需求
      headerObj: {
        Authorization: 'Bearer ' + getToken()
      },
    }
  },
  watch: {
    // 监听初始时图片列表长度, 与limit相等则隐藏按钮
    fileList: {
      handler() {
        this.checkLimit(this.fileList)
        this.fileChange();
      }
    },
    value: {
      deep: true,  // 深度监听
      handler(val) {
        console.log("图片izhi",val)
        if(val){
          if(Array.isArray(val)){
            this.fileList = [];
            // 图片列表回显
            val.forEach((item,index)=>{
              // this.fileList.push({name:item,url:process.env.VUE_APP_API+"/"+item})
              this.fileList.push({name:item,url:item})
            })
          }else {
            this.fileList = [];
            this.fileList.push({name:val,url:val})
          }
        }
      }
    },
  },
  methods: {
    // 检查对比图片数量,对新增按钮进行隐藏
    checkLimit(filelist) {
      const limit = this.limit
      this.$nextTick(()=>{
        const uploadDom = this.$refs['upload']
        if (filelist.length === limit) {
          uploadDom.$children[1].$el.style.display = 'none'
        } else {
          uploadDom.$children[1].$el.style.display = ''
        }
      })
    },
    // 放大查看图片
    handlePictureCardPreview(file){
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 删除图片
    handleRemove(file) {
      // console.log(file)
      for (let i = 0; i < this.fileList.length; i++) {
        if (this.fileList[i].uid === file.uid) {
          this.fileList.splice(i, 1)
        }
      }
    },
    //监听改变
    fileChange(){
      this.$emit('fileChange',this.fileList)
    },
    //成功上传
    successUpload(response, file, fileList) {
      console.log('执行到这里。。。', response, file, fileList)
      this.fileList.push(file)
    },
    // 选中前钩子
    beforeUpload(file) {
      // console.log("123456",file);
      const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1)
	  // 文件类型
      const whiteList = ['jpg', 'jpeg', 'png']
      // 验证格式
      if (whiteList.indexOf(fileSuffix) === -1) {
        this.$message.error(file.name + '上传文件只能是 jpg、jpeg、png格式')
        this.$refs.upload.handleRemove(file)
        return false
      }

      const isLt5M = file.size / 1024 / 1024 < this.maxSize
      // 验证大小
      if (!isLt5M) {
        setTimeout(() => {
          this.$message.error(file.name + '上传文件大小不能超过 '+ this.maxSize +'MB')
        }, 10)
        this.$refs.upload.handleRemove(file)
        return false
      }
    },

  }
}
</script>

在需要调用的页面使用如下:

html 复制代码
<!--showText:显示文案,value:例如修改页显示图片,max-size:图片最大大小,limit:最多上传数量,fileChange:改变时回调-->
<x-upload-img-list :showText="true" :value="form.imgList" :max-size="5" :limit="6" @fileChange="pictureChange"></x-upload-img-list>

<script>
import XUploadImgList from "@/components/FormField/XUploadImgList";
components: {
  XUploadImgList
},
methods :{
	// 图片上传组件回调--可以操作成自己想要的
	pictureChange(e){
	  console.log('图片上传回调',e)
	  this.form.slideshowList = []
	  e.forEach((item,index)=>{
	    if(item.response){
	      this.form.slideshowList.push(process.env.VUE_APP_API+"/"+item.response.data)
	    }else {
	      this.form.slideshowList.push(item.url)
	    }
	  })
	  this.form.slideshow = this.form.slideshowList.join(','); // 使用逗号将数组转换为字符串
	},
}

</script>

好啦,这是关于一篇vue2的多图上传组件,如果有什么问题及时跟小编联系哦,如果喜欢的话记得给小编三连哈,小伙伴们如果有什么好的组件记得跟小编分享下哦

相关推荐
百万蹄蹄向前冲1 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5812 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路2 小时前
GeoTools 读取影像元数据
前端
ssshooter3 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry3 小时前
Jetpack Compose 中的状态
前端
dae bal4 小时前
关于RSA和AES加密
前端·vue.js
柳杉4 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog4 小时前
低端设备加载webp ANR
前端·算法
LKAI.5 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
刺客-Andy5 小时前
React 第七十节 Router中matchRoutes的使用详解及注意事项
前端·javascript·react.js