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

相关推荐
高山我梦口香糖33 分钟前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_7482352436 分钟前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240251 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar1 小时前
纯前端实现更新检测
开发语言·前端·javascript
落魄实习生2 小时前
AI应用-本地模型实现AI生成PPT(简易版)
python·ai·vue·ppt
寻找沙漠的人2 小时前
前端知识补充—CSS
前端·css
GISer_Jing2 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245522 小时前
吉利前端、AI面试
前端·面试·职场和发展
理想不理想v3 小时前
webpack最基础的配置
前端·webpack·node.js
pubuzhixing3 小时前
开源白板新方案:Plait 同时支持 Angular 和 React 啦!
前端·开源·github