Home  >  Article  >  Web Front-end  >  How to implement file drag and upload function with progress bar in Vue

How to implement file drag and upload function with progress bar in Vue

亚连
亚连Original
2018-06-05 11:52:082349browse

This article mainly introduces the Vue implementation of the file dragging and uploading function with a progress bar. This article introduces it to you in great detail through example code and has reference value. Friends who need it can refer to it

1. Basic interface

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport"
   content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet">
 <script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
 <style>
  .dropbox {
   border: .25rem dashed #007bff;
   min-height: 5rem;
  }
 </style>
 <title>Document</title>
</head>
<body>
<p id="app" class="m-5">
 <p class="dropbox p-3">
  <h2 class="text-center">把要上传的文件拖动到这里</h2>
 </p>
</p>
<script>
 new Vue({
  el: &#39;#app&#39;,
  data: {},
  methods: {},
  mounted: function () {}
 });
</script>
</body>
</html>

##2. Detect drag events

First let the page support file dragging, add code in Vue's mounted() function:

mounted: function () {
 var dropbox = document.querySelector(&#39;.dropbox&#39;);
 dropbox.addEventListener(&#39;dragenter&#39;, this.onDrag, false);
 dropbox.addEventListener(&#39;dragover&#39;, this.onDrag, false);
 dropbox.addEventListener(&#39;drop&#39;, this.onDrop, false);
}

When a file is dragged to the drag area of ​​the browser, three events will be triggered. :

  1. When the file enters the drag area for the first time, the dragenter event is triggered.

  2. When the file is dragged back and forth in the drag area, it is continuously triggered. dragover event

  3. The file is already in the drag area and when the mouse is released, the drop event is triggered

To implement dragging and uploading, we only need Pay attention to the drop event. However, the other two events also need to be monitored in order to prevent the browser's default behavior. If it is not blocked, then when you drag the file to the browser, the browser will automatically download the file (default behavior), and the drop event will not be triggered.

The event listening function is added to the methods object of Vue:

methods: {
 uploadFile: function (file) {
  console.log(file);
 },
 onDrag: function (e) {
  e.stopPropagation();
  e.preventDefault();
 },
 onDrop: function (e) {
  e.stopPropagation();
  e.preventDefault();
  var dt = e.dataTransfer;
  for (var i = 0; i !== dt.files.length; i++) {
   this.uploadFile(dt.files[i]);
  }
 }
},

In the onDrop() function, the basic information of the file dragged by the user to the browser can be obtained through e.dataTransfer.files Information, the uploadFile() function now prints out only this information. You can understand that each file dragged to the browser is a File object:

3. Handle drag events

Now, we need to add functionality to the uploadFile() function so that when a file is dragged, the file name and an upload progress bar appear in the drag area .

First define the files attribute in Vue's data object to save the names of all files dragged to the browser. Then whenever the uploadFile() function is called, save the file name and upload progress to files:

data: {
 files: []
},
methods: {
 uploadFile: function (file) {
  var item = {
   name: file.name,
   uploadPercentage: 67
  };
  this.files.push(item);
 },
}

The upload progress function will be introduced later, first write a fixed value.

Correspondingly, in the HTML code, use the v-for keyword to display each item of files:

<p class="dropbox p-3">
 <h2 class="text-center">把要上传的文件拖动到这里</h2>
 <p class="border m-2 d-inline-block p-4" style="width:15rem" v-for="file in files">
  <h5 class="mt-0">{{ file.name }}</h5>
  <p class="progress">
   <p class="progress-bar progress-bar-striped"
     :style="{ width: file.uploadPercentage+&#39;%&#39; }"></p>
  </p>
 </p>
</p>

Moreover, the prompt "Drag the file to be uploaded here" only It is only displayed when there is no file in the drag area:

55eca8f7610bf82aba9544aa7a15244b Drag the uploaded file here2e9b454fa8428549ca2e64dfac4625cd

In this way, the drag effect will be:

##4. File uploadNext to implement real file upload, continue to add code to the uploadFile() function:

uploadFile: function (file) {
 var item = {
  name: file.name,
  uploadPercentage: 67
 };
 this.files.push(item);
 var fd = new FormData();
 fd.append(&#39;myFile&#39;, file);

 var xhr = new XMLHttpRequest();
 xhr.open(&#39;POST&#39;, &#39;upload.php&#39;, true);
 xhr.send(fd);
},

FormData is used here, and the file to be uploaded is attached to on the FormData and sent to the PHP side through AJAX. PHP side code:

if (isset($_FILES[&#39;myFile&#39;])) {
 move_uploaded_file($_FILES[&#39;myFile&#39;][&#39;tmp_name&#39;], &#39;uploads/&#39; . $_FILES[&#39;myFile&#39;][&#39;name&#39;]);
 echo &#39;OK&#39;;
} else {
 echo &#39;No file specified&#39;;
}

Now refresh the page and drag the two files on your computer into the browser. The PHP side will receive and save the files to the uploads directory:

Tips: If PHP returns No file specified when dragging and dropping, or $_FILES is NULL, it is possible that PHP limits the maximum bytes of the POST request, or limits the size of the uploaded file. At this time, you need to adjust these two configurations in php.ini:

post_max_size = 20M // POST请求的最大字节数
upload_max_filesize = 20M // 上传文件的最大体积

Display of progress barThe basic upload function is completed , and finally we complete the progress bar. Whenever an AJAX request sends data for a period of time, a progress event will be generated. We can listen to the progress event to know the current upload progress:

uploadFile: function (file) {
  ...
  xhr.upload.addEventListener(&#39;progress&#39;, function (e) {
    item.uploadPercentage = Math.round((e.loaded * 100) / e.total);
  }, false);
  xhr.send(fd);
},

e.loaded represents how many bytes are currently sent by AJAX, e .total represents the total number of bytes sent by AJAX. These two properties allow you to calculate the upload progress percentage.

In this way, a file drag and upload function with a progress bar is completed.

Attachment: The complete code

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
     content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
  <style>
    .dropbox {
      border: .25rem dashed #007bff;
      min-height: 5rem;
    }
  </style>
  <title>Document</title>
</head>
<body>
<p id="app" class="m-5">
  <p class="dropbox p-3">
    <h2 v-if="files.length===0" class="text-center">把要上传的文件拖动到这里</h2>
    <p class="border m-2 d-inline-block p-4" style="width:15rem" v-for="file in files">
      <h5 class="mt-0">{{ file.name }}</h5>
      <p class="progress">
        <p class="progress-bar progress-bar-striped"
           :style="{ width: file.uploadPercentage+&#39;%&#39; }"></p>
      </p>
    </p>
  </p>
</p>
<script>
  new Vue({
    el: &#39;#app&#39;,
    data: {
      files: []
    },
    methods: {
      uploadFile: function (file) {
        var item = {
          name: file.name,
          uploadPercentage: 0
        };
        this.files.push(item);
        var fd = new FormData();
        fd.append(&#39;myFile&#39;, file);
        var xhr = new XMLHttpRequest();
        xhr.open(&#39;POST&#39;, &#39;upload.php&#39;, true);
        xhr.upload.addEventListener(&#39;progress&#39;, function (e) {
          item.uploadPercentage = Math.round((e.loaded * 100) / e.total);
        }, false);
        xhr.send(fd);
      },
      onDrag: function (e) {
        e.stopPropagation();
        e.preventDefault();
      },
      onDrop: function (e) {
        e.stopPropagation();
        e.preventDefault();
        var dt = e.dataTransfer;
        for (var i = 0; i !== dt.files.length; i++) {
          this.uploadFile(dt.files[i]);
        }
      }
    },
    mounted: function () {
      var dropbox = document.querySelector(&#39;.dropbox&#39;);
      dropbox.addEventListener(&#39;dragenter&#39;, this.onDrag, false);
      dropbox.addEventListener(&#39;dragover&#39;, this.onDrag, false);
      dropbox.addEventListener(&#39;drop&#39;, this.onDrop, false);
    }
  });
</script>
</body>
</html>

The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

How to implement the dialog box in Vue

How to use the compile operation method in Vue

About the dialog box el-dialog closing event in element ui (detailed tutorial)

The above is the detailed content of How to implement file drag and upload function with progress bar in Vue. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn