vue3.x + elementPlus 封装组件之update 上传图片

老规矩----前面文章的步骤创建文件导入js等

1. 上才艺

<template>
  <div v-if="type == 'upload'" class="mjb-upload flex">
    <!-- 没有默认图的展示 -->
    <div v-if="!isDefaultimg" class="whupload">
      <div
        v-for="(item, j) in uploadDataAll.dialogImageUrlList"
        :key="'img'+j"
        class="u-img-all u-img-all-d cp"
        draggable="true"
        @dragstart="handleDragStart($event, item)"
        @dragover.prevent="handleDragOver($event, item)"
        @dragenter="handleDragEnter($event, item)"
        @dragend="handleDragEnd($event, item)"
        @mouseleave="imgMouseleave(item)"
        @mouseenter="imgMouseenter(item)"
      >
        <div class="img-box">
          <el-icon class="i-icon-suc"><Check /></el-icon>
          <el-image :src="item.url" fit="scale-down" />
        </div>
        <span class="img-hover" :class="item.show ? 't100' : ' '">
          <span class="u-preview" @click.stop="handlePictureCardPreview(item, j)">
            <el-icon class="el-icon-zoom-in"><ZoomIn /></el-icon>
          </span>
          <span class="u-delete" @click.stop="handleRemove(item, j)">
            <el-icon class="el-icon-delete"><Delete /></el-icon>
          </span>
        </span>
      </div>
      <el-upload
        v-loading="uploadDataAll.pictLoading"
        :action="actionUrl"
        :headers="headers"
        :multiple="multiple"
        :limit="limit"
        list-type="picture-card"
        class="disinb "
        :before-upload="beforeAvatarUpload"
        :on-success="uploadSuccess"
        :on-error="uploadError"
      >
        <el-icon class="el-icon-plus"><Plus /></el-icon>
      </el-upload>
    </div>
    <!-- 有默认图 -->
    <div v-else class="whupload">
      <div
        v-for="(item, j) in uploadDataAll.dialogImageUrlListDef"
        :key="'img'+j"
        class="u-img-all u-img-all-d cp"
        draggable="true"
        @dragstart="handleDragStartDef($event, item)"
        @dragover.prevent="handleDragOverDef($event, item)"
        @dragenter="handleDragEnterDef($event, item)"
        @dragend="handleDragEndDef($event, item)"
        @mouseleave="imgMouseleaveDef(item)"
        @mouseenter="imgMouseenterDef(item)"
      >
        <el-radio v-if="uploadDataAll.defaultimgUrlListIndex.includes(j)" v-model="uploadDataAll.radio" :label="j" @change="defaultRadio"> </el-radio>
        <div class="img-box">
          <el-icon class="i-icon-suc"><Check /></el-icon>
          <el-image :src="item.url" fit="scale-down" />
        </div>
        <span class="img-hover" :class="item.show ? 't100' : ' '">
          <span class="u-preview" @click.stop="handlePictureCardPreviewDef(item, j)">
            <el-icon class="el-icon-zoom-in"><ZoomIn /></el-icon>
          </span>
          <span class="u-delete" @click.stop="handleRemoveDef(item, j)">
            <el-icon class="el-icon-delete"><Delete /></el-icon>
          </span>
        </span>
      </div>
      <el-upload
        v-loading="uploadDataAll.pictLoadingDef"
        :action="actionUrl"
        :headers="headers"
        :multiple="multiple"
        :limit="limit"
        list-type="picture-card"
        class="disinb "
        :before-upload="beforeAvatarUploadDef"
        :on-success="uploadSuccessDef"
        :on-error="uploadErrorDef"
      >
        <el-icon class="el-icon-plus"><Plus /></el-icon>
      </el-upload>
    </div>
    <el-dialog v-model="uploadDataAll.dialogVisible" title="查看大图" width="50%" draggable :before-close="handleClose">
      <el-carousel ref="remarkCaruselUp" :interval="5000" arrow="always" :autoplay="false">
        <el-carousel-item
          v-for="(item, i) in uploadDataAll.dialogImageUrlList"
          :key="i"
          :name="'i' + i"
        >
          <el-image class="up-d-img" :src="item.url" fit="scale-down" />
        </el-carousel-item>
      </el-carousel>
    </el-dialog>
    <!-- 默认图片的展示 -->
    <el-dialog v-model="uploadDataAll.dialogDefVisible" title="查看默认图片" width="50%" draggable :before-close="handleCloseDef">
      <el-carousel ref="remarkCaruselDef" :interval="5000" arrow="always" :autoplay="false">
        <el-carousel-item
          v-for="(item, i) in uploadDataAll.dialogImageUrlListDef"
          :key="i"
          :name="'index' + i"
        >
          <el-image class="up-d-img" :src="item.url" fit="scale-down" />
        </el-carousel-item>
      </el-carousel>
    </el-dialog>
    <!-- 没有默认图的弹窗 -->
    <ZLDialog
      :dialog-object="dialogObjDel"
      :title="dialogObjDel.title"
      @dialogClose="dialogClose"
      @dialogSuccess="dialogSuccess"
    >
      <div class="ptb16 t-c">删除之后不可复原</div>
    </ZLDialog>
    <!-- 有默认图的弹窗 -->
    <ZLDialog
      :dialog-object="dialogObjDelDef"
      :title="dialogObjDelDef.title"
      @dialogClose="dialogCloseDef"
      @dialogSuccess="dialogSuccessDef"
    >
      <div class="ptb16 t-c">删除之后不可复原</div>
    </ZLDialog>
  </div>
  <div v-else class="upload-img-look">
    <el-upload
      v-if="!tableImgData.dialogImageUrlList.length"
      v-loading="tableImgData.loading"
      list-type="picture-card"
      :auto-upload="false"
      :headers="headers"
      :action="actionUrl"
      :on-success="handleAvatarSuccess"
      :on-error="handleAvatarError"
      :before-upload="beforeAvatarTableUpload"
    >
      <el-icon class="el-icon-plus"><Plus /></el-icon>
    </el-upload>
    <div
      v-for="(item, i) in tableImgData.dialogImageUrlList"
      v-else
      :key="i"
      v-loading="tableImgData.loading"
      class="u-img-all cp posr"
      draggable="true"
      @dragstart="handleDragStartTable($event, item)"
      @dragover.prevent="handleDragOverTable($event, item)"
      @dragenter="handleDragEnterTable($event, item)"
      @dragend="handleDragEndTable($event, item)"
      @mouseleave="imgTableMouseleave(item)"
      @mouseenter="imgTableMouseenter(item)"
    >
      <div class="img-box">
        <el-image :src="item.url" fit="scale-down" />
      </div>
      <div class="img-hover" :style="item.show ? 'top:0' : 'top:-72px'">
        <span class="u-preview" @click.stop="lookImg(item, i)">
          <i class="el-icon-view"></i>
        </span>
        <!-- :on-progress="handleAvatarProgress" -->
        <el-upload
          class="u-add"
          :headers="headers"
          :action="actionUrl"
          :show-file-list="false"
          :on-success="handleAvatarSuccess"
          :on-error="handleAvatarError"
          :before-upload="beforeAvatarTableUpload"
        >
          <el-icon class="el-icon-plus"><Plus /></el-icon>
        </el-upload>
        <span class="u-delete" @click.stop="delImg(item, i)">
          <el-icon class="el-icon-delete"><Delete /></el-icon>
        </span>
      </div>
    </div>
    <!-- 查看 -->
    <ZLDialog
      :dialog-object="tableImgData.dialogObjImg"
      :title="tableImgData.dialogObjImg.title"
      @dialogClose="dialogTableClose"
    >
      <el-carousel ref="remarkCarusel" arrow="always" :autoplay="false">
        <el-carousel-item
          v-for="(item, index) in tableImgData.dialogObjImg.imgList"
          :key="index"
          :name="'index' + index"
        >
          <img :src="item.url" class="sku-banner" alt="" />
        </el-carousel-item>
      </el-carousel>
    </ZLDialog>
    <!-- 删除 -->
    <ZLDialog
      :dialog-object="tableImgData.dialogObjImgDel"
      :title="tableImgData.dialogObjImgDel.title"
      @dialogClose="dialogCloseDel"
      @dialogSuccess="dialogSuccessDel"
    >
      <div>确定删除当前选中的图片吗?</div>
    </ZLDialog>
    <!-- </div> -->
  </div>
</template>

<script>
import { reactive, ref, nextTick } from 'vue'
import OnlyMessage from '@/utils/onlyMsgbox'
// 删除弹框数据
const dialogObjDel = reactive({
  dialogVisible: false,
  title: '是否要删除当前图片?',
  width: '30%',
  successBtnText: '确定',
  closeBtnText: '取消',
  isFooter: true // 是否显示按钮
})
// 删除弹框数据
const dialogObjDelDef = reactive({
  dialogVisible: false,
  title: '是否要删除当前图片?',
  width: '30%',
  successBtnText: '确定',
  closeBtnText: '取消',
  isFooter: true // 是否显示按钮
})
const uploadDataAll = reactive({
  dialogVisible: false,
  delFile: null, // 删除的问题
  delIndex: -1, // 删除图片的索引
  dragging: null, // 拖动的变量
  pictLoading: false, // 上传loading
  // 有默认图的
  radio: '-1',
  defRadioCur: null, // 单选在的数据保存
  defaultimgUrlListIndex: [],
  dialogImageUrlList: [], // 弹窗图片的展示
  dialogDefVisible: false, // 默认图弹框
  dialogImageUrlListDef: [], // 默认图数据
  draggingDef: null,
  pictLoadingDef: false
  // actionUrl: 'https://fileapi.manjd.com/app/community/v1/app/pic/upload',
})
// 表格图片的变量
const tableImgData = reactive({
  dragging: null,
  loading: false,
  dialogObjImg: {
    dialogVisible: false,
    title: '查看大图',
    isFooter: false,
    width: '40%',
    imgList: []
  },
  dialogObjImgDel: {
    dialogVisible: false,
    title: '删除图片',
    isFooter: true,
    width: '30%',
    curIndex: -1,
    curItem: null
  },
  dialogImageUrlList: []
})
const remarkCaruselUp = ref(null) // 查看大图的ref
const remarkCaruselDef = ref(null) // 查看大图的ref
// 页面初始化
const initUploadEffect = (props) => {
  const _init = () => {
    // 是否有默认图
    if (props.isDefaultimg) {
      uploadDataAll.dialogImageUrlListDef.length = 0
      props.defaultimgUrlList.forEach((e, i) => {
        uploadDataAll.defaultimgUrlListIndex.push(i)
      })
      uploadDataAll.dialogImageUrlListDef = uploadDataAll.dialogImageUrlListDef.concat(props.defaultimgUrlList)
    }
    if (!props.isDefaultimg && props.type === 'upload') {
      uploadDataAll.dialogImageUrlList = uploadDataAll.dialogImageUrlList.concat(props.imgUrlList)
    }
    // 是否是表格里面的图片
    if (props.type === 'tableImg') {
      tableImgData.dialogImageUrlList = props.imgUrlList
    }
  }
  return { _init }
}
// 非表格上传图片
const uploadImgListEffect = (props, ctx) => {
  // 上传图片成功
  const uploadSuccess = (response, file, fileList) => {
    if (response.code === 1) {
      uploadDataAll.pictLoading = false
      fileList.forEach((e) => {
        e.show = false
      })
      uploadDataAll.dialogImageUrlList = fileList
      ctx.emit('sucUpload', response, file, fileList)
    } else {
      uploadDataAll.pictLoading = false
      console.log(response)
    }
  }
  // 上传图片失败  回调
  const uploadError = (err, file, fileList) => {
    fileList.forEach((e) => {
      e.show = false
    })
    uploadDataAll.dialogImageUrlList = fileList
    uploadDataAll.pictLoading = false
    ctx.emit('errUpload', err, file, fileList)
    return
  }
  // 上传图片前
  const beforeAvatarUpload = (file) => {
    uploadDataAll.pictLoading = true
    ctx.emit('beforeUpload', file)
  }
  return { uploadSuccess, uploadError, beforeAvatarUpload }
}
// 非表格查看大图的弹框 删除
const lookBigImgDialogEffect = (props, ctx) => {
  // 删除图片   唤起弹窗
  const handleRemove = (file, j) => {
    if (uploadDataAll.defaultimgUrlListIndex.includes(j)) {
      OnlyMessage.error('默认图片禁止删除!')
      return
    }
    dialogObjDel.dialogVisible = true
    uploadDataAll.delFile = file
    uploadDataAll.delIndex = j
  }
  // 查看图片
  const handlePictureCardPreview = (file, j) => {
    uploadDataAll.dialogVisible = true
    nextTick(() => {
      remarkCaruselUp.value.setActiveItem('i' + j)
    })
  }
  // 关闭弹窗
  const dialogClose = () => {
    dialogObjDel.dialogVisible = false
  }
  const handleClose = () => {
    uploadDataAll.dialogVisible = false
  }
  // 删除成功
  const dialogSuccess = () => {
    uploadDataAll.dialogImageUrlList.splice(uploadDataAll.delIndex, 1)
    ctx.emit('delUpload', uploadDataAll.delFile, uploadDataAll.delIndex)
    dialogObjDel.dialogVisible = false
  }
  return { handlePictureCardPreview, dialogClose, dialogSuccess, handleRemove, handleClose }
}
// 非表格数据hover事件
const uploadImgHoverEffect = () => {
  // 上传图片的鼠标事件
  const imgMouseleave = (item) => {
    uploadDataAll.dialogImageUrlList.forEach((e, i) => {
      if (e.uid === item.uid) {
        e.show = false
      }
    })
  }
  const imgMouseenter = (item) => {
    uploadDataAll.dialogImageUrlList.forEach((e, i) => {
      if (e.uid === item.uid) {
        e.show = true
      }
    })
  }
  return { imgMouseleave, imgMouseenter }
}
// 非表格的图片拖动事件
const uploadImgDragEffect = (props, ctx) => {
  // 拖动
  const handleDragStart = (e, items) => {
    uploadDataAll.dragging = items // 开始拖动时,暂时保存当前拖动的数据。
  }
  const handleDragEnd = (e, items) => {
    // console.log(items)
    // console.log(this.dialogImageUrlList);
    uploadDataAll.dragging = null // 拖动结束后,清除数据
    ctx.emit('dragEnd', uploadDataAll.dialogImageUrlList)
  }
  const handleDragOver = (e) => {
    e.dataTransfer.dropEffect = 'move' // 在dragenter中针对放置目标来设置!
  }
  const handleDragEnter = (e, items) => {
    e.dataTransfer.effectAllowed = 'move' // 为需要移动的元素设置dragstart事件
    if (items === uploadDataAll.dragging) return
    const newItems = [...uploadDataAll.dialogImageUrlList] // 拷贝一份数据进行交换操作。
    const src = newItems.indexOf(uploadDataAll.dragging) // 获取数组下标
    const dst = newItems.indexOf(items)
    newItems.splice(dst, 0, ...newItems.splice(src, 1)) // 交换位置
    uploadDataAll.dialogImageUrlList = newItems
  }
  return { handleDragStart, handleDragEnd, handleDragOver, handleDragEnter }
}

// 非表格默认图上传图片
const uploadImgListDefEffect = (props, ctx) => {
  // 上传图片成功
  const uploadSuccessDef = (response, file, fileList) => {
    if (response.code === 1) {
      uploadDataAll.pictLoadingDef = false
      fileList.forEach((e) => {
        e.show = false
      })
      uploadDataAll.dialogImageUrlListDef = uploadDataAll.dialogImageUrlListDef.concat(fileList)
      ctx.emit('sucUpload', response, file, fileList)
    } else {
      uploadDataAll.pictLoadingDef = false
      console.log(response)
    }
  }
  // 上传图片失败  回调
  const uploadErrorDef = (err, file, fileList) => {
    fileList.forEach((e) => {
      e.show = false
    })
    // uploadDataAll.dialogImageUrlListDef = fileList
    uploadDataAll.pictLoadingDef = false
    ctx.emit('errUpload', err, file, fileList)
    return
  }
  // 上传图片前
  const beforeAvatarUploadDef = (file) => {
    uploadDataAll.pictLoadingDef = true
    ctx.emit('beforeUpload', file)
  }
  return { uploadSuccessDef, uploadErrorDef, beforeAvatarUploadDef }
}
// 非表格有默认图查看大图的弹框 删除
const lookBigImgDialogDefEffect = (props, ctx) => {
  // 删除图片   唤起弹窗
  const handleRemoveDef = (file, j) => {
    if (uploadDataAll.defaultimgUrlListIndex.includes(j)) {
      OnlyMessage.error('默认图片禁止删除!')
      return
    }
    dialogObjDelDef.dialogVisible = true
    uploadDataAll.delFile = file
    uploadDataAll.delIndex = j
    // console.log(uploadDataAll.dialogImageUrlListDef)
    // console.log(uploadDataAll.delFile)
    // console.log(uploadDataAll.delIndex)
  }
  // 查看图片
  const handlePictureCardPreviewDef = (file, j) => {
    uploadDataAll.dialogDefVisible = true
    nextTick(() => {
      remarkCaruselDef.value.setActiveItem('index' + j)
    })
  }
  // 关闭弹窗
  const dialogCloseDef = () => {
    dialogObjDelDef.dialogVisible = false
  }
  // 删除成功
  const dialogSuccessDef = () => {
    uploadDataAll.dialogImageUrlListDef.splice(uploadDataAll.delIndex, 1)
    ctx.emit('delUpload', uploadDataAll.delFile, uploadDataAll.delIndex)
    dialogObjDelDef.dialogVisible = false
  }
  const handleCloseDef = () => {
    uploadDataAll.dialogDefVisible = false
  }
  return { handlePictureCardPreviewDef, dialogCloseDef, dialogSuccessDef, handleRemoveDef, handleCloseDef }
}
// 非表格数据有默认图hover事件
const uploadImgHoverDefEffect = () => {
  // 默认图片展示的单选
  const defaultRadio = (label) => {
    uploadDataAll.defRadioCur = uploadDataAll.dialogImageUrlListDef[label]
  }
  // 上传图片的鼠标事件
  const imgMouseleaveDef = (item) => {
    uploadDataAll.dialogImageUrlListDef.forEach((e, i) => {
      if (e.uid === item.uid) {
        e.show = false
      }
    })
  }
  const imgMouseenterDef = (item) => {
    uploadDataAll.dialogImageUrlListDef.forEach((e, i) => {
      if (e.uid === item.uid) {
        e.show = true
      }
    })
  }
  return { imgMouseleaveDef, imgMouseenterDef, defaultRadio }
}
// 非表格的有默认图 图片拖动事件
const uploadImgDragDefEffect = (props, ctx) => {
  // 拖动
  const handleDragStartDef = (e, items) => {
    uploadDataAll.draggingDef = items // 开始拖动时,暂时保存当前拖动的数据。
  }
  const handleDragEndDef = (e, items) => {
    // console.log(items)
    // console.log(this.dialogImageUrlList);
    uploadDataAll.draggingDef = null // 拖动结束后,清除数据
    ctx.emit('dragEnd', uploadDataAll.dialogImageUrlListDef)
  }
  const handleDragOverDef = (e) => {
    e.dataTransfer.dropEffect = 'move' // 在dragenter中针对放置目标来设置!
  }
  const handleDragEnterDef = (e, items) => {
    e.dataTransfer.effectAllowed = 'move' // 为需要移动的元素设置dragstart事件
    if (items === uploadDataAll.draggingDef) return
    const newItems = [...uploadDataAll.dialogImageUrlListDef] // 拷贝一份数据进行交换操作。
    const src = newItems.indexOf(uploadDataAll.draggingDef) // 获取数组下标
    const dst = newItems.indexOf(items)
    newItems.splice(dst, 0, ...newItems.splice(src, 1)) // 交换位置
    uploadDataAll.dialogImageUrlListDef = newItems
  }
  return { handleDragStartDef, handleDragEndDef, handleDragOverDef, handleDragEnterDef }
}
// 表格的图片处理方法
const tableUploadImgEffect = (props, ctx) => {
  // table里面的小图片的展示
  const beforeAvatarTableUpload = (file) => {
    tableImgData.loading = true
    const isJPG = file.type === 'image/jpeg'
    const isLt2M = file.size / 1024 / 1024 < 2
    if (!isJPG) {
      OnlyMessage.error('上传头像图片只能是 JPG 格式!')
      tableImgData.loading = false
    }
    if (!isLt2M) {
      OnlyMessage.error('上传头像图片大小不能超过 2MB!')
      tableImgData.loading = false
    }
    return isJPG && isLt2M
  }
  const lookImg = (item, i) => {
    console.log('查看')
    tableImgData.dialogObjImg.dialogVisible = true
    tableImgData.dialogObjImg.imgList = tableImgData.dialogImageUrlList
    this.$refs.remarkCarusel.setActiveItem('index' + i)
  }
  const delImg = (item, i) => {
    console.log('删除')
    tableImgData.dialogObjImgDel.dialogVisible = true
    tableImgData.dialogObjImgDel.curIndex = i
    tableImgData.dialogObjImgDel.curItem = item
  }
  const dialogTableClose = () => {
    tableImgData.dialogObjImg.dialogVisible = false
  }
  const dialogCloseDel = () => {
    tableImgData.dialogObjImgDel.dialogVisible = false
  }
  const dialogSuccessDel = () => {
    tableImgData.dialogObjImgDel.dialogVisible = false
    // this.dialogImageUrlList.splice(tableImgData.dialogObjImgDel.curIndx, 1);
    // tableImgData.dialogObjImg.imgList.splice(tableImgData.dialogObjImgDel.curIndx, 1);
    ctx.emit(
      'delUploadImg',
      props.row,
      tableImgData.dialogObjImgDel.curItem,
      tableImgData.dialogObjImgDel.curIndex
    )
  }
  const handleAvatarSuccess = (response, file, fileList) => {
    tableImgData.loading = false
    ctx.emit('scuUploadImg', response, file, fileList, props.row)
  }
  const handleAvatarError = (err, file, fileList) => {
    tableImgData.loading = false
    console.log(err)
    ctx.emit('errUploadImg', err, file, fileList)
  }
  const imgTableMouseleave = (item) => {
    item.show = false
  }
  const imgTableMouseenter = (item) => {
    item.show = true
  }
  // 拖动
  const handleDragStartTable = (e, items) => {
    tableImgData.dragging = items // 开始拖动时,暂时保存当前拖动的数据。
  }
  const handleDragEndTable = (e, items) => {
    // console.log(items)
    // console.log(this.dialogImageUrlList);
    tableImgData.dragging = null // 拖动结束后,清除数据
    ctx.emit('dragUploadEnd', tableImgData.dialogImageUrlList)
  }
  const handleDragOverTable = (e) => {
    e.dataTransfer.dropEffect = 'move' // 在dragenter中针对放置目标来设置!
  }
  const handleDragEnterTable = (e, items) => {
    e.dataTransfer.effectAllowed = 'move' // 为需要移动的元素设置dragstart事件
    if (items === tableImgData.dragging) return
    var newItems = [...tableImgData.dialogImageUrlList] // 拷贝一份数据进行交换操作。
    var src = newItems.indexOf(tableImgData.dragging) // 获取数组下标
    var dst = newItems.indexOf(items)
    newItems.splice(dst, 0, ...newItems.splice(src, 1)) // 交换位置
    tableImgData.dialogImageUrlList = newItems
  }
  return { beforeAvatarTableUpload, lookImg, delImg, dialogTableClose,
    dialogCloseDel, dialogSuccessDel, handleAvatarSuccess, handleAvatarError,
    handleDragStartTable, imgTableMouseenter, imgTableMouseleave,
    handleDragEndTable, handleDragOverTable, handleDragEnterTable
  }
}
export default {
  props: {
    // 区分是否只是上传图片  不是上传图片就是在table里面显示的小图片
    type: {
      default() {
        return 'upload'
      },
      type: String
    },
    // 是否展示默认图片
    isDefaultimg: {
      default() {
        return false
      },
      type: Boolean
    },
    // 请求头
    headers: {
      default() {
        return {}
      },
      type: Object
    },
    // 是否自动播放
    autoplay: {
      default() {
        return false
      },
      type: Boolean
    },
    // 是否支持多选上传
    multiple: {
      default() {
        return true
      },
      type: Boolean
    },
    // 多选上传个数
    limit: {
      default() {
        return 9
      },
      type: Number
    },
    // m默认上传的图片
    defaultimgUrlList: {
      default() {
        return []
      },
      type: Array
    },
    // 上传地址
    actionUrl: {
      default() {
        return ''
      },
      type: String
    },
    // 表格里面的图片查看和上传
    row: {
      // 表格哪一行的数据回调展示
      default() {
        return {}
      },

      type: Object
    },
    // 表格里面的图片展示/默认的图片展示
    imgUrlList: {
      default() {
        return []
      },
      type: Array
    }
  },
  emits: ['delUpload', 'sucUpload', 'errUpload', 'beforeUpload', 'dragEnd', 'delUploadImg', 'errUploadImg', 'scuUploadImg', 'dragUploadEnd'],
  setup(props, ctx) {
    const { _init } = initUploadEffect(props)
    const { uploadSuccess, uploadError, beforeAvatarUpload } = uploadImgListEffect(props, ctx)
    const { handlePictureCardPreview, dialogClose, dialogSuccess, handleRemove, handleClose } = lookBigImgDialogEffect(props, ctx)
    const { imgMouseleave, imgMouseenter } = uploadImgHoverEffect()
    const { handleDragStart, handleDragEnd, handleDragOver, handleDragEnter } = uploadImgDragEffect(props, ctx)
    // 有默认图的
    const { uploadSuccessDef, uploadErrorDef, beforeAvatarUploadDef } = uploadImgListDefEffect(props, ctx)
    const { imgMouseleaveDef, imgMouseenterDef, defaultRadio } = uploadImgHoverDefEffect()
    const { handlePictureCardPreviewDef, dialogCloseDef, dialogSuccessDef, handleRemoveDef, handleCloseDef } = lookBigImgDialogDefEffect(props, ctx)
    const { handleDragStartDef, handleDragEndDef, handleDragOverDef, handleDragEnterDef } = uploadImgDragDefEffect(props, ctx)
    // 表格图片方法
    const { beforeAvatarTableUpload, lookImg, delImg, dialogTableClose,
      dialogCloseDel, dialogSuccessDel, handleAvatarSuccess, handleAvatarError,
      handleDragStartTable, imgTableMouseenter, imgTableMouseleave,
      handleDragEndTable, handleDragOverTable, handleDragEnterTable } = tableUploadImgEffect(props, ctx)
    _init()
    return {
      uploadDataAll, tableImgData, remarkCaruselUp, remarkCaruselDef, dialogObjDel, dialogClose,
      dialogSuccess, handleRemove, handleClose,
      defaultRadio, handlePictureCardPreviewDef, uploadSuccess,
      uploadSuccessDef, uploadErrorDef, beforeAvatarUploadDef, dialogObjDelDef,
      handlePictureCardPreview, dialogCloseDef, dialogSuccessDef, handleRemoveDef, handleCloseDef,
      imgMouseleaveDef, imgMouseenterDef,
      handleDragStartDef, handleDragEndDef, handleDragOverDef, handleDragEnterDef,
      uploadError, beforeAvatarUpload, imgMouseleave,
      imgMouseenter, handleDragStart, handleDragEnd,
      handleDragOver, handleDragEnter,
      beforeAvatarTableUpload, lookImg, delImg,
      dialogTableClose, dialogCloseDel, dialogSuccessDel,
      handleAvatarSuccess, handleAvatarError, handleDragStartTable,
      imgTableMouseenter, imgTableMouseleave, handleDragEndTable,
      handleDragOverTable, handleDragEnterTable
    }
  }
}
</script>

<style lang="scss">
.mjb-upload {
  .whupload {
    display: flex;
    height: 100px;
  }
  .el-upload-list--picture-card .el-upload-list__item {
    width: 100px;
    height: 100px;
    position: relative;
  }
  .el-upload-list__item.is-success {
    display: none !important;
  }
  .el-upload--picture-card {
    width: 100px;
    height: 100px;
    background: transparent;
    // border-color: #333;
    border: none;
    display: flex;
    align-items: center;
  }
  .el-upload-list .el-upload-list--picture-card {
    display: flex;
  }
  .el-upload-list--picture .el-upload-list__item {
    display: inline-block;
    width: 200px;
    width: 90px;
    margin-right: 5px;
  }
  // .el-upload-list__item-name,
  // .el-upload-list.el-upload-list--picture-card,
  // .el-icon-close-tip {
    // display: none !important;
  // }
  .el-upload-list--picture-card .el-upload-list__item-actions span + span {
    margin-left: 0;
  }
  .el-dialog__body {
    padding: 0;
  }
  .el-dialog__wrapper {
    width: 70%;
    left: 50%;
    margin-left: -35%;
  }
  .el-carousel__item {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .up-d-img {
    width: auto;
    height: auto;
  }
  .u-img-all::after {
    content: "";
    border-top: 10px solid #45dc51;
    border-right: 10px solid #45dc51;
    border-left: 10px solid transparent;
    border-bottom: 10px solid transparent;
    position: absolute;
    top: 0;
    right: 8px;
    border-radius: 0 4px 0 0;
  }

  .u-img-all {
    // display: flex;
    display: inline-block;
    position: relative;
    overflow: hidden;
    height: 100%;
    i.el-icon-upload-success.el-icon-check {
      position: absolute;
      top: 0px;
      right: 8px;
      font-size: 10px;
      z-index: 20;
      color: #fff;
    }
    .img-box {
      width: 98px;
      height: 100%;
      border: 1px solid #45dc51;
      display: flex;
      align-items: center;
      border-radius: 4px;
      box-sizing: border-box;
      margin-right: 8px;
      .i-icon-suc {
        position: absolute;
        top: 0;
        right:8px;
        z-index: 21;
        font-size: 10px;
        color:#fff;
      }
    .el-image__inner{
      vertical-align: middle;
    }
    }
    img {
      width: 100%;
      height: auto;
    }
    img:nth-child(2) {
      margin-left: 0;
    }
    .img-hover {
      position: absolute;
      top: -100%;
      left: 0;
      width: 100px;
      height: 100px;
      background: rgba(0, 0, 0, 0.5);
      border-radius: 4px;
      transition: all 0.3s;
      z-index: 21;
      .u-preview {
        width: 28px;
        height: 28px;
        position: absolute;
        top: 36px;
        left: 15px;
        i.el-icon-zoom-in {
          position: absolute;
          top: 0;
          left: 0;
          color: #fff;
          font-size: 26px;
        }
      }
      .u-delete {
        width: 28px;
        height: 28px;
        position: absolute;
        top: 36px;
        left: 55px;
        i.el-icon-delete {
          position: absolute;
          top: 0;
          left: 0;
          color: #fff;
          font-size: 26px;
        }
      }
    }
    .img-hover.t100 {
      top: 0;
    }
  }
  .u-img-all-d {
    .el-radio {
      margin-right: 0;
      position: absolute;
      top: 3px;
      left: 50%;
      transform: translateX(-50%);
      z-index: 10;
      .el-radio__label {
        display: none;
      }
    }
  }
  .el-upload--picture-card i.el-icon-plus {
    @include color_primary($color-text-blue);
    position: relative;
  }
  .el-icon-plus::after {
    content: "";
    position: absolute;
    left: -36px;
    top: -36px;
    width: 100px;
    height: 100px;
    border-radius: 4px;
    background-color: transparent;
    border-style: dashed;
    border-width: 1px;
    @include border_primary($bg-blue);
  }
}

.upload-img-look {
  display: flex;
  align-items: center;
  justify-content: center;
  .el-upload--picture-card i {
    font-size: 14px;
  }
  .el-upload--picture-card {
    width: 70px;
    height: 70px;
    line-height: 70px;
  }
  .sku-banner {
    width: auto;
    height: 100%;
  }
  .u-img-all-d {
    margin-right: 8px;
  }
  .u-img-all {
    display: inline-block;
    min-width: 70px;
    height: 70px;
    line-height: 70px;
    border-width: 1px;
    border-style: dashed;
    @include border_primary($bg-blue);
    border-radius: 8px;
    overflow: hidden;
    margin-right: 8px;

    .img-box {
      width: 70px;
      height: 70px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
      box-sizing: border-box;
    }
    .el-image__inner{
      vertical-align: middle;
    }
    .img {
      display: inline-block;
      width: 100%;
      height: 100%;
    }
    .img-hover {
      display: flex;
      position: absolute;
      top: -72px;
      width: 100%;
      justify-content: space-around;
      background: rgba(0, 0, 0, 0.5);
      transition: all 0.3s;
      border-radius: 8px;
      i.el-icon-view,
      .el-icon-delete,
      .u-add .el-icon-plus {
        color: #fff;
      }
    }
  }
}
</style>

2.使用

<template>
  <div>
    <span>支持批量上传、拖拽换位</span>
    <!-- 支持拖拽换位 -->
    <LZUpload
      :action-url="uploadData.actionUrl"
      :autoplay="uploadData.autoplay"
      :multiple="uploadData.multiple"
      :limit="uploadData.limit"
      :headers="uploadData.headers"
      @beforeUpload="beforeUpload"
      @sucUpload="sucUpload"
      @errUpload="errUpload"
      @delUpload="delUpload"
      @dragEnd="dragEnd"
    ></LZUpload>
    <span>支持批量上传、拖拽换位、有默认图的</span>
    <!-- 支持拖拽换位 -->
    <LZUpload
      is-defaultimg
      :defaultimg-url-list="uploadData.defaultimgUrlList"
      :action-url="uploadData.actionUrl"
      :autoplay="uploadData.autoplay"
      :multiple="uploadData.multiple"
      :limit="uploadData.limit"
      :headers="uploadData.headers"
      @beforeUpload="beforeUpload"
      @sucUpload="sucUpload"
      @errUpload="errUpload"
      @delUpload="delUpload"
      @dragEnd="dragEnd"
    ></LZUpload>
    <div>表格里面的小图片上传展示</div>
    <LZUpload
      type="tableImg"
      :img-url-list="uploadData.imgUrlList"
      :autoplay="uploadData.autoplay"
      :headers="{}"
      @delUploadImg="delUploadImg"
      @scuUploadImg="scuUploadImg"
      @errUploadImg="errUploadImg"
      @dragUploadEnd="dragUploadEnd"
    ></LZUpload>
  </div>
</template>
<script>
import { reactive, ref } from 'vue'
import OnlyMessage from '@/utils/onlyMsgbox'
const uploadData = reactive({
  autoplay: false, // 查看大图是否自动滚动 默认不滚动
  multiple: true, // 是否支持多选上传 默认是
  limit: 9, // 多上传的个数  默认9
  actionUrl: 'https://devapi.yunxiaofu.net/official/upload/v1/app/businesslicense', // 上传的地址
  headers: {
    token: '',
    appversion: ''
  },
  imgUrlList: [
    {
      url: 'https://t7.baidu.com/it/u=4198287529,2774471735&fm=193&f=GIF',
      show: false
    },
    {
      url: 'https://t7.baidu.com/it/u=2851687453,2321283050&fm=193&f=GIF',
      show: false
    }
  ],
  defaultimgUrlList: [
    {
      uid: 1,
      url: 'https://t7.baidu.com/it/u=738441947,1208408731&fm=193&f=GIF'
    },
    {
      uid: 2,
      url: 'https://t7.baidu.com/it/u=1415984692,3889465312&fm=193&f=GIF'
    },
    {
      uid: 3,
      url: 'https://t7.baidu.com/it/u=4080826490,615918710&fm=193&f=GIF'
    }
  ]
})
export default {
  name: 'UploadImg',
  setup() {
    // 上传前
    const beforeUpload = (file) => {
      console.log(file)
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        OnlyMessage.error('上传头像图片只能是 JPG 格式!')
      }
      if (!isLt2M) {
        OnlyMessage.error('上传头像图片大小不能超过 2MB!')
      }
      return isJPG && isLt2M
    }
    // 删除某一个
    const delUpload = (file, i) => {
      console.log(file, i)
    }
    // 成功回调
    const sucUpload = (response, file, fileList) => {
      console.log(response, file, fileList)
    }
    // 失败回调
    const errUpload = (err, file, fileList) => {
      console.log(err, file, fileList)
    }
    // 拖拽完成
    const dragEnd = (fileList) => {
      console.log(fileList)
    }
    const delUploadImg = (row, item, i) => {
      console.log(row)
      console.log(item)
      console.log(i)
      // row && row.j.splice(i, 1)
    }
    const scuUploadImg = (response, file, fileList, row) => {
      console.log(response, file, fileList, row)
      // row && row.j.push({
      //   show: true,
      //   url: response.data
      // })
    }
    const errUploadImg = (err, file, fileList) => {
      console.log(err, file, fileList)
    }
    const dragUploadEnd = (arr) => {
      console.log(arr)
    }
    return { uploadData, beforeUpload, delUpload, sucUpload, errUpload, dragEnd, delUploadImg, scuUploadImg, errUploadImg, dragUploadEnd }
  }
}
</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值