vue封装input file,多文件上传组件

效果预览图

在这里插入图片描述

  1. 定义组件vue组件,props接收[“uploadID”, “number”, “file”, “operation”],上传图片的id,图片数量,文件url,文件操作。
//上传一张图片
 <UploadFile
        :uploadID="produploadID"
        :number="1"
        :operation="operation"
        :file="file"
        ref="upload"
      ></UploadFile>
 //上传多张图片设置number
  <UploadFile
      :uploadID="produploadID"
      :number="3"
      :operation="operation"
      :file="file"
      ref="upload"
    ></UploadFile>
  1. UploadFile.vue,封装input案例中引用了element-ui的按钮组件.
//选择文件
<el-button size="small" type="primary" class="btn">
        <input type="file" class="fileupload" value="file" :id="uploadID" name="img" accept="image/*" @change="onchange"/>选择文件
</el-button>
//选择多文件
<el-button size="small" type="primary" class="btn">
        <input type="file" class="fileupload" value="file" :id="uploadID" name="img" accept="image/*" @change="onchangemulty" multiple/>选择多文件
</el-button>

3.图片渲染区域

<div class="uploadarea" v-if="picture.length">
      <div v-for="(item,key) in picture" :key="key" class="image" @mouseenter="imgmouseenter(key)" @mouseleave="imgmouseleave(key)">
        <div class="progress">
          <el-progress
            type="circle"
            :percentage="item.progress"
            :width="150"
            v-show="item.progress!=100"
          ></el-progress>
        </div>
        <img :src="item.url" alt class="img" />
        <div class="triangle" v-show="!item.mouseenter && item.progress==100">
          <i slot="suffix" class="el-icon-check icon"></i>
        </div>
        <div class="mousehover" v-show="item.mouseenter && item.progress==100">
          <div @click="preview(item.url)">
            <i class="el-icon-search"></i>
          </div>
          <div @click="deleteimg(key)">
            <i class="el-icon-delete"></i>
          </div>
        </div>
      </div>
 </div>
  1. css
.uploadarea {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
}
.image {
  width: 150px;
  height: 150px;
  margin-right: 10px;
  margin-top: 5px;
  position: relative;
  border-radius: 5px;
  overflow: hidden;
  border: 1px dashed #eee;
}
.img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.triangle {
  width: 0;
  height: 0;
  border-top: 25px solid #13ce66;
  border-left: 25px solid transparent;
  position: absolute;
  top: 0;
  right: 0;
}
.progress {
  position: absolute;
  top: 0;
  background: #fff;
}
.mousehover {
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  color: #fff;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-around;
}
.mousehover div {
  width: 20px;
  height: 20px;
  position: relative;
  cursor: pointer;
}
.mousehover div i {
  position: absolute;
  top: 0;
  left: 0;
}

.icon {
  position: absolute;
  top: -25px;
  right: 0px;
  color: #fff;
}

5.单图上传处理方法。FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。其中File对象可以是来自用户在一个元素上选择文件后返回的FileList对象

onchange(e) {
      if (this.picture.length == this.number) {
        this.$message("只能上传" + this.number + "个文件");
      } else {
        var file = e.target.files[0];
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onloadstart = e => {
          var obj = {
            url: "",
            mouseenter: false,
            progress: 0
          };
          this.picture.push(obj);
        };
        //上传文件精度条
        reader.onprogress = e => {
          var clock = setInterval(() => {
            var p = Math.abs(Math.floor(Math.random() * (25 - 35 + 1)) + 25);
            this.picture[this.picture.length - 1].progress += p;
            if (this.picture[this.picture.length - 1].progress >= 99) {
              clearInterval(clock);
              let max = e.total;
              let progress = (e.loaded / max) * 100;
              this.picture[this.picture.length - 1].url = e.target.result;
              this.picture[this.picture.length - 1].progress = progress;
            }
          }, 500);
        };
        reader.onloadend = e => {};
      }
    },

6.多文件上传处理

onchangemulty(e) {
    if (this.picture.length == this.number) {
      this.$message("只能上传" + this.number + "个文件");
      return false;
    }
    var file = e.target.files;
    for (let i = 0; i < this.number; i++) {
      var reader = new FileReader();
      reader.readAsDataURL(file[i]);
      reader.onloadstart = e => {
        var obj = {
            url: "",
            mouseenter: false,
            progress: 0
        };
        this.picture.push(obj);
      };
      //上传文件精度条
      reader.onprogress = e => {
        var clock = setInterval(() => {
          var p = Math.abs(Math.floor(Math.random() * (10 - 35 + 1)) + 10);
          this.picture[i].progress += p;
          if (this.picture[i].progress >= 99) {
            clearInterval(clock);
            let max = e.total;
            let progress = (e.loaded / max) * 100;
            this.picture[i].url = e.target.result;
            this.picture[i].progress = progress;
          }
        }, 500);
      };
      reader.onloadend = function(e) {};
    }
  },

7.鼠标悬浮操作

  //鼠标悬浮
    imgmouseenter(key) {
      this.picture[key].mouseenter = true;
      this.picture.forEach((v, k) => {
        if (key == k) {
          v.mouseenter = true;
        } else {
          v.mouseenter = false;
        }
      });
    },
    //鼠标离开
    imgmouseleave(key) {
      this.picture[key].mouseenter = false;
    }

8.删除图片操作

    //删除图片
    deleteimg(key) {
      this.$confirm("此操作将删除上传文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          this.picture.forEach((v, k) => {
            if (key == k) {
              this.picture.splice(k, 1);
            }
          });
          this.$message({
            type: "success",
            message: "删除成功!"
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除"
          });
        });
    },

9.图片预览

 <el-dialog
      :visible.sync="previewdialogVisible"
      width="60%"
      :before-close="handleClose"
      center
      title="图片预览"
      top="5vh"
      class="dialog"
    >
      <div class="p_block">
        <img :src="previewurl" alt="图片预览" />
      </div>
    </el-dialog>
.p_block {
  width: 100%;
  height: 35vw;
}
.p_block img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
 //预览图片
 preview(url) {
   this.previewdialogVisible = true;
   this.previewurl = url;
 },

10,最后在页面引用组件就完成啦

<script>
import UploadFile from "@/components/uploadfile";
export default {
  components: { UploadFile },
  data() {
    return {
      operation: "new",
      number: 1,
      file: "",
      produploadID: "frame",
    };
  },

};
</script>
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值