国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Vue實現帶進度條的文件拖動上傳功能

2019-11-19 14:19:52
字體:
來源:轉載
供稿:網友

1. 基本界面

<!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  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><div id="app" class="m-5"> <div class="dropbox p-3">  <h2 class="text-center">把要上傳的文件拖動到這里</h2> </div></div><script> new Vue({  el: '#app',  data: {},  methods: {},  mounted: function () {} });</script></body></html>

2. 檢測拖動事件

首先讓頁面支持文件拖拽,在 Vue 的 mounted() 函數中添加代碼:

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

當把文件拖動到瀏覽器的拖動區域時,會觸發三種事件:

  1. 文件第一次進入拖動區時,觸發 dragenter 事件
  2. 文件在拖動區來回拖拽時,不斷觸發 dragover 事件
  3. 文件已經在拖動區,并松開鼠標時,觸發 drop 事件

實現拖動上傳,我們只需要關心 drop 事件。不過另外兩個事件也需要監聽,目的是阻止瀏覽器默認行為。如果不阻止,那么把文件拖到瀏覽器時,瀏覽器就會自動下載這個文件(默認行為),drop 事件觸發不出來。

事件的監聽函數添加在 Vue 的 methods 對象中:

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]);  } }},

onDrop() 函數中,通過 e.dataTransfer.files 可以拿到用戶拖動到瀏覽器的文件的基本信息,uploadFile() 函數現在只這些信息打印了出來,可以了解到,拖動到瀏覽器的每個文件都是一個 File 對象:

3. 處理拖動事件

現在,我們要給 uploadFile() 函數增加功能,實現拖動文件時,拖動區出現文件名和一個上傳進度條。

首先在 Vue 的 data 對象中定義 files 屬性,用來保存所有拖動到瀏覽器中文件的名稱。然后在uploadFile() 函數每當被調用時,把文件名和上傳進度保存到 files 中:

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

上傳進度的功能在后面再介紹,先寫一個固定值。

相應地,在HTML代碼中,用 v-for 關鍵字顯示 files 的每一項:

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

而且,“把要上傳的文件拖動到這里” 的提示只在拖動區沒有文件的時候才顯示:

<h2 v-if="files.length===0" class="text-center">把要上傳的文件拖動到這里</h2>

這樣,拖動效果就有了:

4. 文件上傳

接下來實現真正的文件上傳,繼續往 uploadFile() 函數添加代碼:

uploadFile: function (file) { var item = {  name: file.name,  uploadPercentage: 67 }; this.files.push(item); var fd = new FormData(); fd.append('myFile', file); var xhr = new XMLHttpRequest(); xhr.open('POST', 'upload.php', true); xhr.send(fd);},

這里用到了 FormData,把要上傳的文件附在了 FormData 上,并通過AJAX方式發送給PHP端。PHP端代碼:

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

現在刷新下頁面,把電腦上的兩個文件拖到瀏覽器中,PHP端會接收并保存文件到 uploads 目錄:

提示:如果拖放時遇到PHP返回了No file specified,或者 $_FILES 為 NULL 的情況時,有可能是PHP限制了POST請求最大字節,或者限制了上傳文件的體積。這時候需要調整下php.ini中的這兩個配置:

post_max_size = 20M // POST請求的最大字節數upload_max_filesize = 20M // 上傳文件的最大體積

進度條的展示

基本的上傳功能完成了,最后我們來完成進度條。每當AJAX請求發送了一段時間的數據時,都會生成一個 progress 事件,我們可以監聽 progress 事件來知道當前的上傳進度:

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

e.loaded 代表當前AJAX發送了多少字節,e.total 代表AJAX總共要發送多少字節。通過這兩個屬性可以計算上傳進度的百分比。

這樣,一個帶進度條的文件拖動上傳功能就完成了。

附:完整代碼

<!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  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><div id="app" class="m-5">  <div class="dropbox p-3">    <h2 v-if="files.length===0" class="text-center">把要上傳的文件拖動到這里</h2>    <div class="border m-2 d-inline-block p-4" style="width:15rem" v-for="file in files">      <h5 class="mt-0">{{ file.name }}</h5>      <div class="progress">        <div class="progress-bar progress-bar-striped"           :style="{ width: file.uploadPercentage+'%' }"></div>      </div>    </div>  </div></div><script>  new Vue({    el: '#app',    data: {      files: []    },    methods: {      uploadFile: function (file) {        var item = {          name: file.name,          uploadPercentage: 0        };        this.files.push(item);        var fd = new FormData();        fd.append('myFile', file);        var xhr = new XMLHttpRequest();        xhr.open('POST', 'upload.php', true);        xhr.upload.addEventListener('progress', 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('.dropbox');      dropbox.addEventListener('dragenter', this.onDrag, false);      dropbox.addEventListener('dragover', this.onDrag, false);      dropbox.addEventListener('drop', this.onDrop, false);    }  });</script></body></html>

總結

以上所述是小編給大家介紹的Vue實現帶進度條的文件拖動上傳功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 镇江市| 若尔盖县| 盖州市| 萨嘎县| 南澳县| 略阳县| 隆安县| 峡江县| 合山市| 明溪县| 德格县| 大同县| 濉溪县| 昌都县| 内乡县| 兴安盟| 镇坪县| 南漳县| 鱼台县| 长白| 大足县| 泸西县| 合作市| 温泉县| 集贤县| 宝鸡市| 中宁县| 鄱阳县| 福鼎市| 金堂县| 张家川| 灵台县| 三原县| 库伦旗| 梅河口市| 政和县| 林口县| 宣汉县| 敦煌市| 宣城市| 宿州市|