最近在写毕设的时候,在更换头像的地方用了el-upload来上传图片,打算做成的样式为,在上传图片之后会有一个图片的预览图,并且在之后的每次上传图像之后会将之前的上传的图片给顶掉。

实现代码1:

<el-upload
   class="avatar-uploader"
   action="#"
   :auto-upload="false"
   :show-file-list="false"
   :on-change="handleAvatarSuccess"
>
  <img v-if="imageUrl" :src="imageUrl" class="avatar" />
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
export default {
  data() {
    return {
      imageUrl: "",
    };
  },
  methods: {
    handleAvatarSuccess(file) {
      //console.log(file);
      this.imageUrl = URL.createObjectURL(file.raw);
    },
  }
}
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}

实现效果

图片说明

图片说明

图片说明

imageUrl的值如下
图片说明

实现代码2:

<el-upload
  action="#"
  list-type="picture-card"
  :auto-upload="false"
  :on-change="changePic"
>
<i slot="default" class="el-icon-plus"></i>
</el-upload>
export default {
  data() {
    return {
      realFileList : null, //这个变量,只在后面提交的时候有用到
    };
  },
  methods: {
    changePic(file, fileList) {
      //console.log(file, fileList);
      this.realFileList = file;
      if (fileList.length > 1) fileList.shift();
      if (fileList.lengt == 0) this.realFileList = null;
    }
  }
}

实现效果
图片说明


在代码二中遇到的坑点

在官方用例中

<el-upload
  action="#"
  list-type="picture-card"
  :auto-upload="false">
    <i slot="default" class="el-icon-plus"></i>
    <div slot="file" slot-scope="{file}">
      <img
        class="el-upload-list__item-thumbnail"
        :src="file.url" alt=""
      >
      <span class="el-upload-list__item-actions">
        <span
          class="el-upload-list__item-preview"
          @click="handlePictureCardPreview(file)"
        >
          <i class="el-icon-zoom-in"></i>
        </span>
        <span
          v-if="!disabled"
          class="el-upload-list__item-delete"
          @click="handleDownload(file)"
        >
          <i class="el-icon-download"></i>
        </span>
        <span
          v-if="!disabled"
          class="el-upload-list__item-delete"
          @click="handleRemove(file)"
        >
          <i class="el-icon-delete"></i>
        </span>
      </span>
    </div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
  <img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<script>
  export default {
    data() {
      return {
        dialogImageUrl: '',
        dialogVisible: false,
        disabled: false
      };
    },
    methods: {
      handleRemove(file) {
        console.log(file);
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      handleDownload(file) {
        console.log(file);
      }
    }
  }
</script>

这个slot是一个坑

<div slot="file" slot-scope="{file}">
      <img
        class="el-upload-list__item-thumbnail"
        :src="file.url" alt=""
      >
</div>

起初的想法:

<el-upload
  action="#"
  list-type="picture-card"
  :auto-upload="false"
  :on-change="changePic"
  ref="upload"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file">
   <img
    class="el-upload-list__item-thumbnail"
    :src="realFileList.url"
    alt=""
   />
</div>
</el-upload>
export default {
  data() {
    return {
      realFileList : null, 
    };
  },
  methods: {
    changePic(file, fileList) {
      //console.log(file, fileList);
      this.realFileList = file;
    }
  }
}

结果
图片说明

其中的file与fileList的值分别为

图片说明