【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 小时前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜052 小时前
React - 组件通信
前端·react.js·前端框架
Amy_cx2 小时前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing9992 小时前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
后海 0_o3 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构
Scabbards_3 小时前
CPT304-2425-S2-Software Engineering II
前端
小满zs3 小时前
Zustand 第二章(状态处理)
前端·react.js
程序猿小D3 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim
萌萌哒草头将军3 小时前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js
狼性书生3 小时前
uniapp实现的简约美观的星级评分组件
前端·uni-app·vue·组件