Vue el-upload 组件多张图片本地上传,使用action上传的地址支持截图粘贴上传

该文章展示了如何在Vue.js应用中创建一个MultiUpload.vue组件,支持图片的多选上传、粘贴上传、预览、移除等功能。组件通过el-upload与后端API交互,限制了最大上传图片数量,并提供了错误提示。同时,文章指出该组件不包含粘贴上传时的进度条展示和自定义上传接口的实现。
摘要由CSDN通过智能技术生成

MultiUpload.vue 组件

<template>
  <div>
    <div tabindex="0" class="pasteArea" :class="{'active': isActive}" @paste="handlePaste" @focus="handleFocus" @blur="handleBlur">
      <div class="iconPicture">
        <i class="el-icon-picture iconWidth" style="color:#3670ff;font-size:28px" />
      </div>
      <div class="description">将截图按Ctrl+V 粘贴至此处</div>
    </div>
    <div class="prompt">本地图片或者多张图片请使用本地上传“+”(支持拓展名:.jpg .png .gif)</div>
    <el-upload
      ref="upload"
      :action="uploadUrl()"
      list-type="picture-card"
      accept=".jpg,.jpeg,.png,.gif"
      multiple
      :file-list="fileList"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :before-upload="handleBeforeUpload"
      :on-preview="handlePreview"
      :limit="maxCount"
      :on-exceed="handleExceed"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" :alt="dialogImageName">
    </el-dialog>
  </div>
</template>
<script>

import { getImageUpload } from '@/api/badFruit'
export default {
  name: 'MultiUpload',
  props: {
    // 图片属性数组
    value: {
      type: Array,
      default: () => []
    },
    // 最大上传图片数量
    maxCount: {
      type: Number,
      default: 5
    }
  },
  data() {
    return {
      fileList: [],
      imagesList: [],
      images: [],
      dialogVisible: false,
      dialogImageUrl: null,
      dialogImageName: '',
      isActive: false,
      num: 0,
      fileNum: 0
    }
  },
  created() {
    // 上传组件显示列表
    this.fileList = this.value
    // 图片保存数组
    this.imagesList = this.value
  },
  methods: {
    // 文件上传地址
    uploadUrl() {
      return getImageUpload
    },
    handleRemove(file, fileList) {
      const list = JSON.parse(JSON.stringify(fileList))
      this.imagesList = list.map(item => ({
        name: item.name,
        url: item.url
      }))
      this.$emit('input', this.imagesList)
    },
    handlePreview(file) {
      this.dialogVisible = true
      this.dialogImageUrl = file.url
      this.dialogImageName = file.name
    },
    handleUploadSuccess(res, file) {
      // console.log(res, file)
      if (res.code === '200') {
        const { message, path } = res.data
        if (message === '图片上传成功') {
          this.images.push({
            name: file.name,
            url: path
          })
          this.num++
          if (this.num === this.fileNum) {
            this.num = 0
            this.fileNum = 0
            // 这里如果 this.value.push(imageUrl) 这么写,vue会报出警告,大概意思是value作为props不应该在子组件中被修改
            // 应该根据 value 得到新的值,而不能修改它,this.value.concat(imageUrl)也是可以的,concat方法返回新的数组
            this.imagesList = this.imagesList.concat(this.images)
            this.$emit('input', this.imagesList)
            this.images = []
          }
        } else {
          this.$message.error(message)
        }
      }
    },
    handlePaste(e) {
      const items = (e.clipboardData || window.clipboardData).items
      let file = null
      if (!items || items.length === 0) {
        this.$message.error('当前浏览器不支持粘贴本地图片,请打开图片复制后再粘贴!')
        return
      }
      // 搜索剪切板items
      for (let i = 0; i < items.length; i++) {
        if (items[i].type.indexOf('image') !== -1) { // 此行代码注释掉,可以上传所有类型的文件
          file = items[i].getAsFile()
          break
        }
      }
      console.log('已上传文件个数:' + this.imagesList.length)
      if (file && this.imagesList.length < this.maxCount) { // 对复制黏贴的类型进行判断,若是非文件类型,比如复制黏贴的文字,则不会调用上传文件的函数
        // 生成预览图
        this.$refs.upload.handleStart(file)
        // 提交上传
        this.$refs.upload.$refs['upload-inner'].upload(file)
      } else {
        if (this.imagesList.length === this.maxCount) {
          this.$message({
            message: '最多只能上传' + this.maxCount + '张图片',
            type: 'warning',
            duration: 1000
          })
        }
      }
    },
    handleFocus() {
      this.isActive = true
    },
    handleBlur() {
      this.isActive = false
    },
    handleBeforeUpload(file) {
      this.fileNum++
      console.log('上传个数:' + this.fileNum)
    },
    handleExceed(files, fileList) {
      this.$message({
        message: '最多只能上传' + this.maxCount + '张图片',
        type: 'warning',
        duration: 1000
      })
    }
  }
}
</script>
<style scoped lang="scss">
  .pasteArea {
    width: 500px;
    height: 80px;
    border: #dfe6ec dashed 1px;
    border-radius: 6px;
    -webkit-border-radius: 6px;
      .iconPicture {
        width: 26px;
        height: 26px;
        position: relative;
        border: #99b5ff dashed 1px;
        margin: 12px auto 8px;
        .iconWidth {
          position: absolute;
          top: 5px;
          left: 5px;
          z-index: 999;
        }
      }
    .description{
      color: #3670ff;
      font-size: 14px;
      text-align: center;
    }
  }
  .active {
    border: #3670ff dashed 1px !important;
    cursor: pointer;
  }
  .prompt {
    width: 500px;
    color: #b0bcdc;
    font-size: 12px;
    text-align: center;
  }
</style>

展示效果如下:
在这里插入图片描述
注意:本篇是使用action上传的地址,而不是自定义上传http-request实现上传接口,如果使用http-request 把相对应的代码改成http-request 形式。以及本篇未实现粘贴上传时进度条的展示,如果需要可自己研究(如果好了可以留言告知一下),也可以采用http-request自定义的方式实现。
如有问题欢迎留言 ^ ^

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值