scenario

When vue + elementUi framework is used as background management system, the Upload component in elementUi is used to Upload a single picture or a single video. The official website provides single picture uploading and multi-picture uploading. On this basis, it is packaged into a component by adding the progress bar display and single video uploading.

code

uploadFile.vue

<template>
  <div>
    <el-upload
      class="avatar-uploader"
      :action="uploadUrl"
      :headers="{ Authorization: token }"
      :show-file-list="false"
      :on-success="handleSuccess"
      :before-upload="beforeUpload"
      :on-progress="uploadProcess"
    >
      <div v-if=! "" fileFlag && fileType === 'image'">
        <img v-if="fileUrl" :src="fileUrl" class="avatar" />
        <i v-else class="el-icon-plus avatar-uploader-icon" />
      </div>
      <div v-if=! "" fileFlag && fileType === 'video'">
        <video
          v-if="fileUrl"
          :src="fileUrl"
          class="avatar-video"
          controls="controls"
        >Your browser does not support video playback</video>
        <i v-else class="el-icon-plus avatar-uploader-icon" />
      </div>
      <el-progress
        v-if="fileFlag"
        style="margin-top:10px;"
        type="circle"
        :percentage="uploadPercent"
      />
    </el-upload>
  </div>
</template>
Copy the code
<script>
export default {
  props: {
    token: {
      type: String.default: ""
    },
    uploadUrl: {
      type: String.required: true
    },
    fileType: {
      type: String.default: "image"}},data() {
    return {
      fileUrl: "".// Address returned by the interface after the upload is successful
      uploadPercent: 0.// The progress bar displays the progress during upload
      fileFlag: false  // Display file or progress bar identifier
    };
  },
  methods: {
    // Successful upload callback
    handleSuccess(res, file) {
      this.fileFlag = false;
      this.uploadPercent = 0;
      if (res.code === 200) {
        this.fileUrl = res.data;
      } else {
        this.$message.error("Video upload failed, please upload again!"); }},/ / the progress bar
    uploadProcess(event, file, fileList) {
      this.fileFlag = true;
      this.uploadPercent = Math.floor(event.percent);
    },
    beforeUpload(file) {
        // The upload format restriction needs to be determined dynamically}}}; </script>Copy the code

The token and uploadUrl of the props and uploadUrl are passed to the parent component as required, because sometimes a background interface requires a login token to be added to the request headers when uploading a file. UploadUrl is the interface for uploading a file. If fileType is passed to image or video, the img image tag or video tag will be displayed in the view based on fileType.

The meaning of the fields in data can be seen in the comments. Here is the CSS code:

<style lang="scss" scope>
.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: 148px;
  height: 148px;
  line-height: 148px;
  text-align: center;
}
.avatar {
  width: 148px;
  max-height: 148px;
  display: block;
}
.avatar-video {
  width: 200px;
  max-height: 200px;
  display: block;
}
</style>
Copy the code
  • In the parent component parent. Used in vue uploadFile. Vue upload pictures or video

parent.vue

<uploadFile
    :token="token"
    :upload-url="uploadUrl"
    file-type="video"
/>
Copy the code
<script>
    import uploadFile from "./uploadFile.vue";
    export default {
        components: { uploadFile },
        data() {
            return {
                token: "token123".uploadUrl: process.env.VUE_APP_BASE_API + "/file/upload"
            }
        }
    }
</script>
Copy the code

To use the upload function, change the token and uploadUrl to your own. The default value of file-type is “image”. Let’s start optimizing the code:

  • To prevent users from uploading videos or other files in the same place as pictures, include code that limits file formats

Add to uploadfile. vue

    beforeUpload(file) {
      const isImage =
        file.type === "image/jpeg" ||
        file.type === "image/png" ||
        file.type === "image/jpg";
      const isVideo =
        file.type === "video/mp4" ||
        file.type === "video/avi" ||
        file.type === "video/flv";
      const isLt10M = file.size / 1024 / 1024 < 10;
      if(! isLt10M) {this.$message.error("Upload file size cannot exceed 10MB!");
        return false;
      }
      if(! isImage &&this.fileType === "image") {
        this.$message.error("Upload file format wrong!");
        return false;
      }
      if(! isVideo &&this.fileType === "video") {
        this.$message.error("Upload file format wrong!");
        return false; }},Copy the code
  • Add props if you want the child component to uploadfile. vue to display images or videos directly.

Add hasFile to parent component parent. Vue. If you want to echo the link that you want to echo, empty if you don’t want to echo the link

  <SingleImageUpload
    // ...
    :has-file="hasFile"
  />
Copy the code
  data() {
    return {
      // ...
      hasFile: ""
    };
  },
Copy the code

Accepts parameters in child component uploadfile.vue

  props: {
    // ...
    hasFile: {
      type: String.default: ""}},Copy the code

The watch listener is used in the child component, and if a value is passed in, the file address is assigned to fileUrl

  watch: {
    hasFile(val) {
      if (val) {
        this.fileUrl = val;
      } else {
        this.fileUrl = ""; }}}Copy the code