美文网首页
vue element-ui多图上传+删除+拖拽改变图片位置

vue element-ui多图上传+删除+拖拽改变图片位置

作者: w_小伍 | 来源:发表于2020-12-28 10:30 被阅读0次

图片拖拽参考:https://www.pianshen.com/article/78751408835/
图片上传组件

<template>
  <div class="pro-pic inner-upload-single">
    <transition-group tag="div" class="drag-wrap">
      <div class="drag-item" v-for="(file, index) in imgFile" :key="file.Image"
           draggable="true"
           @dragstart="handleDragStart($event, file)"
           @dragover.prevent="handleDragOver($event, file)"
           @dragenter="handleDragEnter($event, file)"
           @dragend="handleDragEnd($event, file)">
        <div
          class="img-box"
          :class="{ borderColorChange:file.Image }"
          @mouseenter="status.showDeleteBtn=index"
          @mouseleave="status.showDeleteBtn=-1">
          <el-upload
            class="avatar-uploader"
            action="#"
            ref="uploader"
            name="upfile"
            :accept="accept"
            :show-file-list="false"
            :on-change="handleAvatarChange(index)"
            :auto-upload="false"
          >
            <div v-if="file.Image">
              <img :src="file.Image" class="avatar" ref="proPic" id="pro-pic">
            </div>
            <i v-else class="el-icon-plus avatar-uploader-icon">
              <img src="@/assets/img/pic.png" alt="" class="img-empty"><br>
              <span>点击上传</span>
            </i>
          </el-upload>
          <div v-if="file.Image&&status.showDeleteBtn==index" class="img-cover-wrap">
            <a href="javascript:;" @click.stop="del(index)" class="del-img-icon">×</a>
          </div>
        </div>
      </div>
    </transition-group>
  </div>
</template>

<script>
  export default {
    name: "uploadMultiImage",
    props: {
      imgFile: {
        type: Array,
        default: () => []
      }
    },
    data() {
      return {
        status: {
          showDeleteBtn: -1
        },
        dragging: null
      }
    },
    computed: {
      accept() {
        return 'image/jpeg,image/jpg'
      }
    },
    methods: {
      handleAvatarChange(index) {
        return file => {
          let params = {
            file,
            index
          }
          this.$emit('avatarChange', params)
        }
      },
      del(index) {
        this.$emit('deleteImg', index)
      },
      handleDragStart(e, item) {
        this.dragging = item
      },
      handleDragEnd(e, item) {
        this.dragging = null
      },
      handleDragOver(e) {
        e.dataTransfer.dropEffect = 'move'
      },
      handleDragEnter(e, item) {
        e.dataTransfer.effectAllowed = "move" //为需要移动的元素设置dragstart事件
        if (item === this.dragging) {
          return
        }
        const newItems = [...this.imgFile]
        const src = newItems.indexOf(this.dragging)
        const dst = newItems.indexOf(item)
        newItems.splice(dst, 0, ...newItems.splice(src, 1))
        // newItems为拖拽后的数组
        console.log(newItems)
        this.$emit('getDragImgFile', newItems)
      }
    }
  }
</script>

<style lang="less" scoped>
  .drag-wrap {
    display: flex;

    .drag-item {
      margin-right: 13px;

      &:last-child {
        margin-right: 0;
      }
    }
  }

  .inner-upload-single {
    margin-left: 10px;
  }

  .avatar-uploader-icon {
    color: #409eff;
    width: 126px;
    height: 126px;
    text-align: center;
    vertical-align: middle;
    display: table-cell;
    text-align: center;
    font-size: 12px;
  }

  .avatar {
    display: block;
    object-fit: scale-down;
  }

  #pro-pic {
    width: 124px;
    height: 124px;
    display: block;
    object-fit: scale-down;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
  }

  .img-empty {
    vertical-align: sub;
    margin-top: 10px;
    margin-bottom: 10px;
  }

  .img-box {
    width: 126px;
    height: 126px;
    background-color: #f9fcff;
    border: dashed 1px #409eff;
    float: left;
    margin-right: 13px;
    position: relative;
  }

  .img-box:last-child {
    margin-right: 0;
  }

  .borderColorChange {
    border: solid 1px #ececec;
    background-color: #f9f9f9;
  }

  .el-icon-plus:before {
    content: "";
  }

  // 删除
  .img-cover-wrap {
    background: rgba(196, 223, 248, .4);
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    cursor: move;

    .del-img-icon {
      width: 24px;
      height: 24px;
      display: block;
      background: #000000;
      border-radius: 50%;
      text-align: center;
      line-height: 22px;
      color: #ffffff;
      font-size: 16px;
      z-index: 10;
      font-size: 20px;
      right: 5px;
      top: 4px;
      position: absolute;
    }
  }
</style>

父组件

<upload-multi-image
      :img-file="form.imgFile"
       @avatarChange="avatarChange($event)"
       @getDragImgFile="getDragImgFile($event)"
       @deleteImg="deleteImg($event)"
        ></upload-multi-image>
data:
form:{ imgFile:[] }

methods: {
    // 上传图片到阿里云
    async avatarChange(e) {
      if (!e.file) {
        return false
      }
      const file = e.file
      const index = e.index
      let testmsg = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase()
      const isLt1M = file.size / 1024 / 1024 < 1
      if (testmsg !== 'jpg' && testmsg !== 'jpeg') {
        this.$message.error('上传图片只能是jpg格式!')
        this.form.imgFile[index].Image = ''
        return false
      }
      if (!isLt1M) {
        this.$message.error('上传图片不能超过1M!')
        this.form.imgFile[index].Image = ''
        return false
      }
      let timestamp = Date.parse(new Date())
      let res = await uploadImg()
      const form = new FormData()
      form.append('policy', _get(res, 'data.policy'))
      form.append('OSSAccessKeyId', _get(res, 'data.accessid'))
      form.append('signature', _get(res, 'data.signature'))
      form.append('key', `${_get(res, 'data.dir')}${_get(res, 'data.key')}${'_'}${timestamp}${'.jpg'}`)
      form.append('success_action_status', 200)
      form.append('file', file.raw)
      const result = await this.$http.post(process.env.OSS_URL, form)
      if (result.status === 200) {
        let url = (process.env.OSS_URL + '/' + `${_get(res, 'data.dir')}${_get(res, 'data.key')}${'_'}${timestamp}${'.jpg'}` + '?fr=upload')
        this.form.imgFile[index].Image = url
        if (this.form.imgFile.length < 5) { // 高级编辑限制5张
          this.form.imgFile.push({Image: ''})
        }
      } else {
        this.$message.error('上传失败!')
      }
    },
    // 删除图片
    deleteImg(index) {
      this.form.imgFile[index].Image = ''
      this.form.imgFile.splice(index,1)
      if (this.form.imgFile.length < 5){
        this.form.imgFile = this.form.imgFile.filter(item => item.Image) //确保只剩一个空的
        this.form.imgFile.push({Image: ''})
      }
    },
    // 获取拖拽后的图片
    getDragImgFile(file) {
      if (file) {
        this.form.imgFile = file
      }
    }
  }

相关文章

网友评论

      本文标题:vue element-ui多图上传+删除+拖拽改变图片位置

      本文链接:https://www.haomeiwen.com/subject/nreznktx.html