【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的多图上传组件,如果有什么问题及时跟小编联系哦,如果喜欢的话记得给小编三连哈,小伙伴们如果有什么好的组件记得跟小编分享下哦

相关推荐
橙子家3 小时前
浏览器缓存之【身份与会话管理】:Cookies 和 Private state tokens
前端
最新资讯动态4 小时前
HDC 2026 | 对话鲸鸿动能:存量时代,品牌如何夺回营销“主动权”?
前端
最新资讯动态4 小时前
游戏出海,从产品走向体系
前端
最新资讯动态5 小时前
20人团队跑出百万DAU、大厂也来抢量:谁在鸿蒙生态跑出加速度
前端
最新资讯动态5 小时前
千万开发者背后,鸿蒙商业化的B面
前端
爱勇宝7 小时前
AI 时代:智商决定起点,情商决定走多远
前端·ai编程
kyriewen7 小时前
用了半年 Claude Code 后,我尝试关掉它写了一周代码——结果比想象中严重
前端·javascript·ai编程
IT_陈寒8 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
徐小夕8 小时前
万字拆解 JitWord:企业级实时协同文档底层架构 + 大模型 AI 融合完整实践
前端·vue.js·github
一份执念9 小时前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序