Ant Design Vue上传多个图片

模板代码:

Ant Design Vue上传多个图片_第1张图片

定义变量:

Ant Design Vue上传多个图片_第2张图片

文件限制的函数:

Ant Design Vue上传多个图片_第3张图片

上传的函数:

Ant Design Vue上传多个图片_第4张图片

样式函数:

Ant Design Vue上传多个图片_第5张图片

完整代码:

<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) => {
      console.log('data.limitError',data.limitError)
      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)
                data.cqImgList = []
              }
              if (data.uploadType === 'tab1') {
                data.nyImgUrl.push(url)
                data.nyImgList = []
              }
            }
          } 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('请上传正确的图片格式!')
      // }
      if (data.uploadType === 'tab') {
        data.cqImgList.push(file)
        data.limitError = (data.cqImgList.concat(...data.cqImgUrl)).length > 5
        // console.log('data.cqImgList',data.cqImgList)
        // console.log('data.cqImgUrl',data.cqImgUrl)
      }
      if (data.uploadType === 'tab1') {
        data.nyImgList.push(file)
        data.limitError = (data.nyImgList.concat(...data.nyImgUrl)).length > 5
        // console.log('data.nyImgList',data.nyImgList)
        // console.log('data.nyImgUrl',data.nyImgUrl)
      }
      console.log('data.limitError',data.limitError)
      if (data.limitError) {
        if (data.uploadType === 'tab') {
          data.cqImgList = []
        }
        if (data.uploadType === 'tab1') {
          data.nyImgList = []
        }
        message.error('厂区图和能源图至多上传五张图片!')
      }
      return !data.limitError
    }

    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>

最终效果:

Ant Design Vue上传多个图片_第6张图片

你可能感兴趣的:(UI框架,vue.js,前端,javascript)