美文网首页
关于vue实现复制粘贴上传图片

关于vue实现复制粘贴上传图片

作者: 給我小鱼干 | 来源:发表于2020-12-25 15:08 被阅读0次

    本插件用到elementUi中的el-upload
    主要能实现点击上传,拖拽上传,截图复制粘贴(鼠标右键操作与Ctrl+C Ctrl+V)上传,网页图片复制粘贴上传,本地图片复制粘贴上传暂时无解
    话不多说上代码

    <template>
      <div class="uploadImage">
        <el-upload
          :file-list="fileList"
          accept="image/*"
          action=""
          ref="uploadBtn"
          drag
          multiple
          list-type="picture-card"
          :limit="maxNum"
          :on-exceed="exceedTips"
          :on-remove="handleRemoveFile"
          :before-upload="handleUploadFile"
          :http-request="uploadFile"
          :on-preview="handlePicturePreview"
        >
          <i class="el-icon-plus"
          ref="uploadImage"
          @paste="handlePaste" 
          contenteditable="" 
          @keydown="handleFocus"></i>
          <div class="el-upload__text">{{uploadText}}</div>
          <div slot="file" slot-scope="{file}">
            <img
              class="el-upload-list__item-thumbnail"
              :src="file.originalUrl" alt="">
            <span class="el-upload-list__item-actions">
              <span
                class="el-upload-list__item-preview"
                @click="handlePicturePreview(file)">
                <i class="el-icon-zoom-in"></i>
              </span>
              <span
                class="el-upload-list__item-delete"
                @click="handleRemoveFile(file)">
                <i class="el-icon-delete"></i>
              </span>
            </span>
          </div>
        </el-upload>
        <el-dialog 
          :visible.sync="dialogVisible" 
          :before-close="onCancel"
          append-to-body>
          <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
      </div>
    </template>
    
    <script>
    import {uploadImageUsingFile} from '@/api/tools/upload'
    export default {
      name: '',
      props: {
        fileList: {
          type: Array,
          default: () => []
        },
        uploadText: {
          type: String,
          default: () => ""
        },
        maxNum:{
          type: Number,
          default: () => 5
        }
      },
      components: {},
      data () {
        return {
          dialogVisible:false,
          dialogImageUrl:''
        }
      },
      computed: {},
      watch: {
        fileList(newVal,oldVal){
          this.$emit('getImage',newVal)
          if(newVal.length>=5){
            document.querySelector('.el-upload').style.display = 'none'
          }else{
            document.querySelector('.el-upload').style.display = 'inline-block'
          }
        }
      },
      created () {
    
      },
      mounted () {
      },
      beforeDestroy () {
    
      },
      methods: {
        handleFocus(){
          this.$refs.uploadImage.blur()
        },
        exceedTips: function () {
          this.$message.error(`最多只能上传${this.maxNum}张图片`)
        },
        handleRemoveFile(file) {
          let num = this.fileList.findIndex(i=>i.originalUrl==file.originalUrl)
          this.fileList.splice(num,1)
        },
        handleUploadFile(file) {
          let isImage = file.type.includes('image')
          let imgCount = this.fileList.length
          if(!isImage){
            this.$message.error('请上传图片格式的文件');
          }
          if(imgCount > this.maxNum){
            this.$message.error(`最多只能上传${this.maxNum}张图片`);
          }
          return isImage && imgCount
        },
        uploadFile(file) {
          //上传文件接口
          uploadImageUsingFile({imageFile: file.file, type: 3})
            .then(value => {
              //设置上传的路径
              if (value.code === '0') {
                this.fileList.push(value.data)
              }else{
                this.$message.error('图片上传失败')
              }
            })
            .catch(err => {
              this.$message.error('图片上传失败')
              console.log(err)
            })
        },
        handlePicturePreview(file){
          this.dialogImageUrl = file.originalUrl;
          this.dialogVisible = true;
        },
        onCancel(){
          this.dialogVisible = false
          this.dialogImageUrl = ''
        },
        handlePaste(event) {
          const items = (event.clipboardData || window.clipboardData).items;
          //去除粘贴到div事件
          event.preventDefault();
          event.returnValue=false;
          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.includes('image')) {
              file = items[i].getAsFile();
              break;
            }
          }
          if (!file) {
            this.$message.error("粘贴内容非图片");
            return;
          }
          this.uploadFile({file:file})
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .uploadImage{
        width: 100%;
        user-select: none;
        >>> .el-form-item__content{
          width: 97%;
          line-height: unset;
        }
        >>> .el-upload-list__item{
          width: 100px;
          height: 100px;
          margin: 0 8px 0 0;
          &.is-ready{
            display: none!important;
          }
          &.is-success{
            >:first-child{
              width: 100%;
              height: 100%;
            }
          }
        }
        >>> .el-upload--picture-card{
          width: 100px;
          height: 100px;
          line-height: unset;
          border: none;
          .el-upload-dragger{
            width: 100px;
            height: 100px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            .el-icon-plus{
              position: absolute;
              width: 100%;
              height: 100%;
              top:20px;
              outline: none;
              caret-color: transparent;
            }
            .el-upload__text{
              font-size: 12px;
              font-weight: 700;
              margin-top: 28px;
              color: #8c939d;
            }
          }
        }
      }
    </style>
    

    网上基本都是键盘操作的复制粘贴功能上传,此处添加鼠标右键粘贴功能

    i标签主要是负责复制粘贴功能 默认的标签是不带编辑功能的 所以使用contenteditable来添加编辑功能,鼠标点击元素右键会出现粘贴复制属性。但是在粘贴时会导致元素可编辑并且粘贴来的内容会添加到元素中展示!!!所以要处理粘贴的默认功能,在handlePaste方法中

    event.preventDefault();
    event.returnValue=false;
    

    这样就不会把内容粘贴到元素中,但是点击也是会出现光标闪动,直接键盘输入也是会输入内容,还是要继续优化,给i标签绑定键盘事件@keydown="handleFocus"移除焦点,注意此处不可绑定@focus事件去除光标,这样会导致我们复制的内容找不到可复制的光标目标而粘贴功能失效,左键粘贴不可点击~~
    虽然禁止了粘贴内容到元素中,但是光标还是能看到,我的笨方法是给i一个样式caret-color: transparent;这个样式是使光标透明~~~

    基本的复制粘贴上传大同小异 本文主要是介绍我遇到的一些小难点

    来吧展示~~~


    image.png

    相关文章

      网友评论

          本文标题:关于vue实现复制粘贴上传图片

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