Ant Design Vue上传多个图片

模板代码:

在这里插入图片描述

定义变量:

在这里插入图片描述

文件限制的函数:

在这里插入图片描述

上传的函数:

在这里插入图片描述

样式函数:

在这里插入图片描述

完整代码:

<template>
  <div class="dialog-upload" v-if="showUploadDialog">
    <div class="dialog-upload__head">
      <div class="title">上传图片</div>
      <div class="close" @click="closeDialog"></div>
    </div>
    <div class="dialog-upload__body">
        <div class="upload-box">
          <span class="text">tab:</span>
          <div class="pic-box">
            <div v-for="(item,index) in cqImgUrl" :key="index" class="pic-box__single">
              <a-image class="pic" :src="item" />
              <div @click="deleteImg('tab',item)" class="pic-delete"></div>
            </div>
            <a-upload
              action="#"
              :multiple="true"
              list-type="picture"
              :before-upload="beforeUpload"
              :customRequest="handleChange"
              :show-upload-list="false"
            >
              <div v-if="!cqImgUrl.length || cqImgUrl.length <5" class="img" @click="uploadImg('tab')"></div>
            </a-upload>
          </div>
        </div>
        <div class="upload-box">
          <span class="text">tab1:</span>
          <div class="pic-box">
            <div v-for="(item,index) in nyImgUrl" :key="index" class="pic-box__single">
              <a-image class="pic" :src="item" />
              <div @click="deleteImg('tab1',item)" class="pic-delete"></div>
            </div>
            <a-upload
              action="#"
              :multiple="true"
              list-type="picture"
              :before-upload="beforeUpload"
              :customRequest="handleChange"
              :show-upload-list="false"
            >
              <div v-if="!nyImgUrl.length || nyImgUrl.length <5" class="img" @click="uploadImg('tab1')"></div>
            </a-upload>
          </div>
        </div>
    </div>
    <div class="dialog-upload__foot">
        <span class="sure" @click="sure">确定</span>
        <span class="cancle" @click="closeDialog">取消</span>
    </div>
  </div>
</template>

<script lang="ts">
import {
    defineComponent, reactive, toRefs, watch, nextTick } from 'vue'
import {
    message } from 'ant-design-vue'
import G from '@/request/G'
import axios from 'axios'

export default defineComponent({
   
  name: 'SmartDialog',
  props: {
   
    showUploadDialog: {
   
      // 是否显示当前弹窗
      type: Boolean,
      default: false
    },
    activeTab: {
   
      type: String,
      default: 'tab'
    },
    imgUrl: {
   
      type: Array,
      default: () => {
   
        return []
      }
    },
    qyStoreId: {
    // 拿到的Id
      type: String,
      default: ''
    }
  },
  setup (props, {
     emit }) {
   
    interface FileItem {
   
      uid: string;
      name?: string;
      status?: string;
      response?: string;
      url?: string;
      percent?:number;
      type?:string;
    }
    interface FileInfo {
   
      file: FileItem;
      fileList: FileItem[];
    }
    const data = reactive({
   
      dialogVisible: false, // 是否显示弹窗
      cqImgUrl: [] as Array<string> | any,
      nyImgUrl: [] as Array<string> | any,
      cqImgList: [] as any,
      nyImgList: [] as any,
      uploadType: '', // 当前上传文件的归属
      limitError: false
    })

    // 监听当前的弹窗是否显示
    watch(
      () => props.showUploadDialog,
      (val: boolean) => {
   
        data.dialogVisible = !!val
      },
      {
   
        immediate: true,
        deep: true
      }
    )

    watch(
      () => props.activeTab,
      (val: string) => {
   
        const type = val === 'tab' ? 2 : 1
        if (props.qyStoreId) {
   
          nextTick(() => {
   
            getPicUrl(type)
          })
        }
      },
      {
   
        immediate: true,
        deep: true
      }
    )

    // 文件上传
    const handleChange = (info: FileInfo) => {
   
      if (!data.limitError) {
   
        const formData = new FormData()
        formData.append('file', info.file as any) // 添加文件对象
        let params = {
   
          biz: 'energy',
          _api: 'el.image.upload',
          _v: '1.0'
        } as any
        params = G.buildInputs(params)
        params._at = G.buildAt(params)
        Object.keys(params).forEach(key => {
   
          formData.append(key, params[key])
        })
        axios.post('/upload', formData).then((res: any) => {
   
          if (res.data && res.data.success && res.data.model) {
   
            if (res.data.model[0]) {
   
              let url = res.data.model[0].authUrl
              if (data.uploadType === 'tab') {
   
                data.cqImgUrl.push(url)
              }
              if (data.uploadType === 'tab1') {
   
                data.nyImgUrl.push(url)
              }
            }
          } else {
   
            message.error(res.data.msgInfo)
          }
        })
      }
    }

    // 获取另一个tab的图,用于回显
    const getPicUrl = (val:number) => {
   
      let params = {
   
        _api: 'el.energy.storeDraw',
        storeId: props.qyStoreId,
        drawType: val,
        _v: '1.0'
      } as any
      params = G.buildInputs(params)
      G.baseAjax({
   
        type: 'POST',
        data: G.param(params) + '&_at=' + G.buildAt(params)
      }).then((res:any) => {
   
        const {
    success, model } = res
        if (success) {
   
          if (props.activeTab === 'tab') {
   
            data.nyImgUrl = model.split(',')
          }

          if (props.activeTab === 'tab1') {
   
            data.cqImgUrl = model.split(',')
          }
        }
      }).finally(() => {
   
        if (props.activeTab === 'tab') {
   
            data.cqImgUrl = JSON.parse(JSON.stringify(props.imgUrl))
          } else if (props.activeTab === 'tab1') {
   
            data.nyImgUrl = JSON.parse(JSON.stringify(props.imgUrl))
          }
      })
    }

    // 关闭弹窗
    const closeDialog = () => {
   
      emit('closeDialog', false)
    }

    // 当前上传的是哪个文件
    const uploadImg = (type:string) => {
   
      data.uploadType = type
    }

    const deleteImg = (type:string, item:string) => {
   
      if (type === 'tab') {
   
        if (data.cqImgUrl && data.cqImgUrl.length) {
   
          let index = data.cqImgUrl.indexOf(item)
          data.cqImgUrl.splice(index,1)
        }
      }
      if (type === 'tab1') {
   
        if (data.nyImgUrl && data.nyImgUrl.length) {
   
          let index = data.nyImgUrl.indexOf(item)
          data.nyImgUrl.splice(index,1)
        }
      }
    }

    const beforeUpload = (file: FileItem) => {
   
      // const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/jpg'
      // if (!isJpgOrPng) {
   
      //   message.error('请上传正确的图片格式!')
      // }
      let sizeLimit = false
      if (data.uploadType === 'tab') {
   
        data.cqImgList.push(file)
        sizeLimit = (data.cqImgList.concat(...data.cqImgUrl)).length <= 5
      }
      if (data.uploadType === 'tab1') {
   
        data.nyImgList.push(file)
        sizeLimit = (data.nyImgList.concat(...data.nyImgUrl)).length <= 5
      }
      if (!sizeLimit && !data.limitError) {
   
        data.limitError = true
        if (data.uploadType === 'tab') {
   
          data.cqImgList = []
        }
        if (data.uploadType === 'tab1') {
   
          data.nyImgList = []
        }
        message.error('至多上传五张图片!')
        return false
      }
      data.limitError = false
      return sizeLimit
    }

    const sure = () => {
   
      let params = {
   
        _api: 'el.energy.addImage',
        storeId: props.qyStoreId,
        factoryDraw: data.cqImgUrl.join(','),
        energyDraw: data.nyImgUrl.join(','),
        _v: '1.0'
      } as any
      params = G.buildInputs(params)
      G.baseAjax({
   
        type: 'POST',
        data: G.param(params) + '&_at=' + G.buildAt(params)
      }).then((res:any) => {
   
        const {
    success } = res
        if (success) {
   
          message.success('上传成功!')
        } else {
   
          message.error(res.msgInfo)
        }
      }).finally(() => {
   
        emit('submitDialog', {
   
          cqImgUrl: data.cqImgUrl,
          nyImgUrl: data.nyImgUrl
        })
      })
    }

    return {
   
      ...toRefs(data),
      closeDialog,
      uploadImg,
      sure,
      handleChange,
      beforeUpload,
      deleteImg
    }
  }
})
</script>

<style lang="scss" scoped>
.dialog-upload {
   
  width: 1056px;
  height: 947px;
  // height: 788px;
  z-index: 200;
  position: absolute;
  top: 20%;
  left: 40%;
  background: url("@/assets/images/uploadDialog.png") no-repeat;
  background-size: 100% 100%;
  overflow: auto;
  &::-webkit-scrollbar {
   
    display: none;
  }
  &__head {
   
    position: relative;
    .title {
   
      padding: 32px 0 77px 48px;
      font-size: 44px;
      font-weight: 600;
      color: #ffffff;
      line-height: 62px;
    }
    .close {
   
      position: absolute;
      top: 24px;
      right: 24px;
      cursor: pointer;
      width: 32px;
      height: 32px;
      background: url("@/assets/images/close.png") no-repeat;
      background-size: 32px auto;
    }
  }
  &__body {
   
    display: flex;
    flex-direction: column;
    .upload-box {
   
        display: flex;
        margin-bottom: 32px;
        .text {
   
          display: inline-block;
          white-space: nowrap;
          width: 236px;
          flex: 1;
          font-size: 28px;
          font-weight: 400;
          color: #fff;
          text-align: right;
        }
        .img {
   
            cursor: pointer;
            width: 200px;
            height: 122px;
            background: url("@/assets/images/upload.png") no-repeat;
            background-size: 200px auto;
        }
    }
    .pic-box {
   
      display: flex;
      flex-wrap: wrap;
      flex: 3;
      &__single {
   
        position: relative;
        width: 200px;
        height: 122px;
        border: 2px dashed #4E93F8;
        border-radius: 8px;
        margin: 0 20px 24px 0;
        .pic  {
   
          width: 200px;
          height: 122px;
          object-fit: contain;
          border-radius: 8px;
        }
        .pic-delete {
   
          cursor: pointer;
          z-index: 200;
          position: absolute;
          z-index: 50;
          top: -16px;
          right: -12px;
          width: 30px;
          height: 30px;
          background: url("@/assets/images/deleteImg.png") no-repeat;
          background-size: 30px auto;
        }
      }
    }
  }
  &__foot {
   
    position: absolute;
    bottom: 40px;
    left: 50%;
    transform: translateX(-50%);
    .sure {
   
        cursor: pointer;
        display: inline-block;
        background: #3196FA;
        border: 2px solid #3196FA;
        border-radius: 8px;
        padding: 12px 41px;
        margin-right: 44px;
        font-size: 28px;
        color: #fff;
    }
    .cancle {
   
        cursor: pointer;
        display: inline-block;
        border: 2px solid #FFFFFF;
        border-radius: 8px;
        padding: 12px 41px;
        font-size: 28px;
        color: #fff;
    }
  }
}
</style>
<style lang="scss">
.dialog-upload {
   
  .ant-image {
   
    width: 196px;
    height: 118px;
    border-radius: 8px;
  }
  .ant-image-img {
   
    width: 196px;
    height: 118px;
    object-fit: contain;
    border-radius: 8px;
  }
  .ant-image-mask-info {
   
   // 将div下的所有元素隐藏文字大小为0
    visibility: hidden;
    font-size: 0; 
  }
  .ant-image-mask-info span{
   
   // 再单独给span标签添加样式 让其显示并且给出文字大小
    visibility: visible;
    font-size: 48px;
  }
}
</style>

最终效果:

在这里插入图片描述

相关推荐

  1. vue2 upload图片

    2024-01-19 13:50:02       33 阅读
  2. uniapp 图片到django后端

    2024-01-19 13:50:02       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-19 13:50:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-19 13:50:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-19 13:50:02       82 阅读
  4. Python语言-面向对象

    2024-01-19 13:50:02       91 阅读

热门阅读

  1. Python设计模式详解

    2024-01-19 13:50:02       48 阅读
  2. What is `JsonSanitizer.sanitize` does?

    2024-01-19 13:50:02       62 阅读
  3. Spring MVC的面试知识点

    2024-01-19 13:50:02       53 阅读
  4. 前端常见面试题之防抖、节流、xss、xsrf

    2024-01-19 13:50:02       50 阅读
  5. 系统架构12 - 数据库基础(下)

    2024-01-19 13:50:02       44 阅读
  6. vue2挂载全局方法/组件

    2024-01-19 13:50:02       53 阅读
  7. el-table点击每一行加背景颜色

    2024-01-19 13:50:02       61 阅读
  8. 第11章 jQuery

    2024-01-19 13:50:02       47 阅读