element多文件上传 报错踩坑记

由于业务需求需要支持多文件上传, 出于复用思想,就把element的上传文件组件进行了二次封装 ,但是多文件上传的时候发现报错: Cannot set property 'status' of null     
踩坑之路开始,  查了下网上说是 fileList 这个值不能修改, 不明所以,  看了下报错是没有获取file对象, 导致了获取文件对象身上的状态报错,下图的 file为null, 猜测是因为此时文件未上传成功, 导致了获取解析文件得到null
    

废话不多说了, 上代码,  

parent component:  

<template>
  <div class="home">
    <el-form ref="form" :model="form" label-width="80px">
    <el-form-item label="图片上传">
        <uploaderImgs
          :imagesList="form.imgs"
          @imageUpload="imageUpload"
          @imageRemove="imageRemove"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">确定</el-button>
        <el-button>取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
// @ is an alias to /src
import uploaderImgs from "@/components/uploaderImgs.vue";

export default {
  name: "Home",
  components: {
    uploaderImgs
  },
  data() {
    return {
      form: {
        imgs: [
         "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
          "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1913214116,3912663704&fm=26&gp=0.jpg",
        ]
      }
    };
  },
  methods: {
    // ---图片
    imageRemove(url) {
      this.form.imgs = this.form.imgs.filter(v => v !== url);
    },
    imageUpload(url) {
      this.form.imgs.push(url);
    },
    // ----
    onSubmit() {
      console.log(this.form);
    }
  }
};
</script>
 
 
Child components:
  
<template>
  <div class="uploader-imgs">
    <el-upload
      ref="upload"
      :action="action"
      :headers="headers"
      list-type="picture-card"
      :before-upload="beforeAvatarUpload"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :on-exceed="handleExceed"
      :file-list="fileList"
      :limit="limit"
      :multiple="multiple"
      :class="[{heidden:imagesList.length >= limit}]"
    >
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt />
    </el-dialog>
  </div>
</template>

<script>
export default {
  props: {
    imagesList: {
      type: Array,
      default() {
        return [];
      }
    },
    limit: {
      type: Number,
      default: 10
    },
    multiple: {
      type: Boolean,
      default: true
    },
    action: {
      required: true,
      type: String,
    },
    headers: {
      type: Object,
      default() {
        return { };
      }
    }
  },
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false
    };
  },
  computed: {
    //   生成回显文件列表
    fileList() {
      if (this.imagesList && this.imagesList.length) {
        return this.imagesList.map(v => {
          let uid = this.createRandomUid();
          return { uid, url: v };
        });
      } else {
        return [];
      }
    }
  },
  methods: {
    //   生成随机uid
    createRandomUid() {
      return Math.random()
        .toString()
        .split(".")[1];
    },
    // 上传限制
    beforeAvatarUpload(file) {
      const isJPG =
        file.type === "image/jpeg" ||
        file.type === "image/gif" ||
        file.type === "image/png" ||
        file.type === "image/jpg";
      const isSize= file.size / 1024 / 1024 < 10;

      if (!isJPG) {
        this.$message.error("上传图片格式有误");
      }
      if (!isSize) {
        this.$message.error("上传头像图片大小不能超过 10MB!");
      }
      return isJPG && isSize;
    },
    // 图片移除
    handleRemove(file, fileList) {
      this.$emit("imageRemove", file.url);
    },
    // 上传成功
    handleSuccess(res, file, fileList) {
      let url = `后台返回来的地址`; 
      //   延迟触发  防止多文件上传报错  如果是多文件模式  则延迟一秒后改变数据  视文件大小决定延迟时间  不然还是会获取不到file对象
      if (this.multiple) {
        setTimeout(() => {
          this.$emit("imageUpload", url);
        }, 1000);
      } else {
        this.$emit("imageUpload", url);
      }
    },
    // 图片预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 超过数量
    handleExceed() {
      this.$message.error("超过最大上传数量,请重新选择");
    }
  }
};
</script>

<style lang="scss">
.uploader-imgs {
  .el-upload-list__item {
    transition: none !important;
  }
  .heidden {
    .el-upload--picture-card {
      display: none;
    }
  }
}
</style>
 
posted @ 2020-07-07 17:36  因一人念一城  阅读(1606)  评论(0编辑  收藏  举报