笔记-vue 自定义上传组件

一、UploadFile文件夹下建index.vue

<template>
  <div>
    <div class="img-up">
      <div
        class="img-list"
        @mouseenter="imgShow = index"
        @mouseleave="imgShow = ''"
        v-for="(item, index) in fileList"
        :key="index"
      >
        <img :src="item.url" class="avatar" />
        <transition name="el-zoom-in-bottom">
          <div class="img-tools" v-show="imgShow === index">
            <i class="el-icon-view img-view"  @click="handlePreview(item)" ></i>
            <i class="el-icon-delete img-del" @click="beforeRemove(item)"></i></div
          ></transition>
      </div>

      <el-upload
        action="#"
        ref="upload"
        accept="image/*"
        :http-request="handleFileUpload"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :before-upload="beforeAvatarUpload"
        :on-exceed="handleExceed"
        :limit="3"
        :show-file-list="false"
      >
        <i v-if="fileList.length < 3" class="el-icon-plus img-btn"></i>
      </el-upload>

    </div>
    <!-- 上传提示 -->
    <div class="el-upload__tip" slot="tip" v-if="isShowTip">
      请上传
      <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
      <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
      的文件
    </div>
    <el-dialog
      append-to-body
      title="图片预览"
      :visible.sync="dialogVisible"
      width="500px"
      style="z-index: 2005;text-align: center;"
    >
      <img :src="dialogImageUrl" style="width: 100%;" alt="" />
    </el-dialog>
  </div>
</template>

<script>
//修改此处api
import { fileUpload } from '@/api/system/file'
import { detectPicture } from '@/api/bussiness/clothes'
export default {
  props: {
    //父组件传入回显参数  ‘1.png,2.png’ 逗号隔开字符串
    value: {
      type: String,
    },
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 5,
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array,
      default: () => ["png", "jpg", "jpeg"],
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true
    },
    interfaceType: {
      type: String,
      default: 'normal'
    }
  },
  data() {
    return {
      loading: false,
      fileList: [], //深拷贝,判断重名及第一步时的文件信息展示
      // baseUrl: APP_PUBLIC_CONFIG.IMG_IRL,//全局变量。拼接图片前缀
      dialogImageUrl: "",
      dialogVisible: false,
      imgShow: "",
    };
  },
  watch: {
    value(v) {
      this.fileList = this.getFlieList(v);
    },
    deep: true,
    immediate: true
  },
  mounted() {},
  methods: {
    //过滤回显参数,将字符串转为数组,不然不能回显
    getFlieList(list) {
      console.log('list',list)
      if (!list) return [];
      return list.split(",").map((e) => {
        return {
          name: e,
          url: e,
        };
      });
    },
    beforeAvatarUpload(file) {
      if (this.fileList > 3) {
        this.handleExceed(this.fileList)
        return
      }
      const isLt2M = file.size / 1024 / 1024 < 3;
      const isJPG = ["image/jpeg", "image/png"];
      if (!isLt2M) {
        this.$message.error("上传图片大小不能超过 3MB!");
        return false;
      }
      if (!isJPG.includes(file.type)) {
        this.$message.error("上传图片只能是 JPG和PNG 格式!");
        return false;
      }
    },
    // 处理移除操作
    handleRemove(file, fileList) {
      let uid = file.uid // 关键作用代码,去除文件列表失败文件
      let idx = this.$refs.upload.uploadFiles.findIndex(item => item.uid === uid)
      this.$refs.upload.uploadFiles.splice(idx, 1)
      this.fileList = this.fileList.filter((e) => e.uid != file.uid).map((e) => ({url:e.url,uid:e.uid,name:e.name}))
      this.$emit("upSuccess", this.fileList.filter((e) => e.uid != file.uid).map((e) => e.url).toString());
    },
    // 处理预览操作
    handlePreview(file) {
      console.log(file)
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 处理超出图片个数操作
    handleExceed(files ) {
      this.$message.warning(
        `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件 `
      );
    },
    // 移除之前的操作
    beforeRemove(file, fileList) {
      return this.$confirm(`确定移除 ${file.name}?`).then(_ => {
        this.handleRemove(file)
      });
    },
    // 处理文件上传操作
    handleFileUpload(file) {
      this.loading = true;
      let randomData = Math.random().toString(10).slice(-10)
      let form = new FormData();
      form.append("file", file.file);
      form.append("requestId",randomData);

      fileUpload(form).then((res) => {
        let param = res.data;
        // 正常接口
        if(this.interfaceType === 'normal') {
          this.fileList.push({ url: param, name: file.file.name });
          //返回上传后的图片数据
          this.$emit("upSuccess", this.fileList.map((e) => e.url).toString());
          this.loading = false;
        }
        // 工服
        if(this.interfaceType === 'workCloth') {
          detectPicture({pictureUrl:res.data}).then(response => {
            console.log('code',response.code)
            if(response.code === 200) {
              this.fileList.push({ url: param, name: file.file.name,uid:file.file.uid });
              //返回上传后的图片数据
              this.$emit("upSuccess", this.fileList.map((e) => e.url).toString());
              this.loading = false;
            }
          }).catch(error => {
            let uid = file.file.uid // 关键作用代码,去除文件列表失败文件
            let idx = this.$refs.upload.uploadFiles.findIndex(item => item.uid === uid)
            this.$refs.upload.uploadFiles.splice(idx, 1)
          })
        }

      });
    },
  },
};
</script>
<style scoped lang="scss">
.img-up {
  display: flex;
  .avatar,
  .img-btn {
    width: 100px;
    height: 100px;
    margin-right: 10px;
  }
  .img-list {
    position: relative;
    .img-tools {
      width: 100px;
      height: 100px;
      background: rgba($color: #000000, $alpha: 0.5);
      position: absolute;
      left: 0;
      top: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .img-del,.img-view {
      color: #fff;
      font-size: 20px;
      cursor: pointer;
    }
    .img-view{
      margin-right: 15px;
    }
  }
}
.img-btn {
  width: 100px;
  height: 100px;
  border: 1px dashed #dcdfe6;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 30px;
  color: #dcdfe6;
}
.transition-box {
  margin-bottom: 10px;
  width: 200px;
  height: 100px;
  border-radius: 4px;
  background-color: #409EFF;
  text-align: center;
  color: #fff;
  padding: 40px 20px;
  box-sizing: border-box;
  margin-right: 20px;
}
</style>

二、页面引用

<template>
		<UploadFile ref="uploadFile" :fileSize="3" :value="form.picture" @upSuccess="(e) => {form.picture = e;}"/>
<template />
<script>
import UploadFile from "@/components/UploadFile";
export default {
	components: { UploadFile },
	data() {
	    //这里存放数据
	    return {
			form: {
              faceLibPersonList: [],
              picture: '',
            }
		}
    }
}

<script/>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值