Ant Design Vue上传多个图片

模板代码:

在这里插入图片描述

定义变量:

在这里插入图片描述

文件限制的函数:

![![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e0c18855525e450ab73b10e98fbd3103.pn](https://img-blog.csdnimg.cn/direct/80d98d0659f0415eb0b6720f9634460c.png

上传的函数:

在这里插入图片描述

样式函数:

在这里插入图片描述

完整代码:

<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 imgUrl1" :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="!imgUrl1.length || imgUrl1.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 imgUrl2" :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="!imgUrl2.length || imgUrl2.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 request from '@/request/request'
import axios from 'axios'

export default defineComponent({
  name: 'dialog',
  props: {
    showUploadDialog: {
      // 是否显示当前弹窗
      type: Boolean,
      default: false
    },
    activeTab: {
      type: String,
      default: 'tab'
    },
    imgUrl: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  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, // 是否显示弹窗
      imgUrl1: [] as Array<string> | any,
      imgUrl2: [] as Array<string> | any,
      imgUrl1List: [] as any,
      imgUrl2List: [] 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) => {
      console.log('data.limitError',data.limitError)
      if (!data.limitError) {
        const formData = new FormData()
        formData.append('file', info.file as any) // 添加文件对象
        let params = {} as any
        Object.keys(params).forEach(key => {
          formData.append(key, params[key])
        })
        axios.post('/upload', formData).then((res: any) => {
          if (res.data) {
              let url = 'XXXX' // 后端返回的url数据
              if (data.uploadType === 'tab') {
                data.imgUrl1.push(url)
                data.imgUrl1List= []
              }
              if (data.uploadType === 'tab1') {
                data.imgUrl2.push(url)
                data.imgUrl2List= []
              }
          } else {
            message.error('报错')
          }
        })
      }
    }

    // 获取另一个tab的图,用于回显
    const getPicUrl = (val:number) => {
      let params = { } as any
      // 请求数据
      request.then((res:any) => {
        const { success, model } = res
        if (success) {
          if (props.activeTab === 'tab') {
            data.imgUrl2= model.split(',')
          }

          if (props.activeTab === 'tab1') {
            data.imgUrl1= model.split(',')
          }
        }
      }).finally(() => {
        if (props.activeTab === 'tab') {
            data.imgUrl1= JSON.parse(JSON.stringify(props.imgUrl))
          } else if (props.activeTab === 'tab1') {
            data.imgUrl2= 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.imgUrl1&& data.imgUrl1.length) {
          let index = data.imgUrl1.indexOf(item)
          data.imgUrl1.splice(index,1)
        }
      }
      if (type === 'tab1') {
        if (data.imgUrl2&& data.imgUrl2.length) {
          let index = data.imgUrl2.indexOf(item)
          data.imgUrl2.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('请上传正确的图片格式!')
      // }
      if (data.uploadType === 'tab') {
        data.imgUrl1List.push(file)
        data.limitError = (data.imgUrl1List.concat(...data.imgUrl1)).length > 5
        // console.log('data.imgUrl1List',data.imgUrl1List)
        // console.log('data.imgUrl1',data.imgUrl1)
      }
      if (data.uploadType === 'tab1') {
        data.imgUrl2List.push(file)
        data.limitError = (data.imgUrl2List.concat(...data.imgUrl2)).length > 5
        // console.log('data.imgUrl2List',data.imgUrl2List)
        // console.log('data.imgUrl2',data.imgUrl2)
      }
      console.log('data.limitError',data.limitError)
      if (data.limitError) {
        if (data.uploadType === 'tab') {
          data.imgUrl1List= []
        }
        if (data.uploadType === 'tab1') {
          data.imgUrl2List= []
        }
        message.error('每张图至多上传五张图片!')
      }
      return !data.limitError
    }

    const sure = () => {
      let params = {} as any
      // 请求数据
      request.then((res:any) => {
        const { success } = res
        if (success) {
          message.success('上传成功!')
        } else {
          message.error('失败')
        }
      }).finally(() => {
        emit('submitDialog', {
          imgUrl1: data.imgUrl1,
          imgUrl2: data.imgUrl2
        })
      })
    }

    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>

最终效果:

在这里插入图片描述

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值