> 文档中心 > Vue+vant实现离线下载

Vue+vant实现离线下载

最近项目需求要实现下载功能,离线后也可以进行访问查看,于是做了一个关于离线下载的功能,在次,整理如下:

<template>    <div> <div class="download_head_tabbar">     <div style="margin-bottom:15px">  <van-nav-bar      title="下载"      left-arrow      @click-left="onClickLeft"  />     </div>     <div>  <van-overlay :show="model_state" @click="show = false">      <div class="wrapper" @click.stop>   <li><van-loading type="spinner" />   </li>   <li style="color: white">加载中~~</li>      </div>  </van-overlay>     </div>     <div>  <div      v-if="fileObj.length <= 0 && downloading.length <= 0"      class="enpty_box"  >      暂无下载~~  </div>  <div>      <div v-show="downloading.length > 0">   <divv-for="(val, index) in downloading":key="index"class="down_item"   ><!--  v-if="downloading_pross[`prossend${id}`] > 0" --><div class="down_item_left">    <li> <span>{{ val.name }}</span>    </li>    <!-- <li><span :style="{width:'30%'}"></span></li> --></div><div class="down_item_right">    <li> <span     v-if="val.state == 0"     class="downloading_icon" >     下载中     <span style="margin-top:3px">  <van-loading size="18px" />     </span> </span> <span     v-else     class="pross"     @click="pause(val.downid)"     >{{  downloading_pross[      `schedule${val.downid}`  ]     }}</span > <span @click="dele_downing(val.downid)">     <van-icon name="cross" /> </span>    </li></div>   </div>      </div>      <div class="downend_box">   <li v-for="(val, index) in fileObj" :key="index"><span    class="downloadtitle"    style="display:flex"    @click="to_detail(val.id)">    <i class="icon iconfont iconbianzu"></i>    {{ val.name }}</span><span @click="dele(val.id, index)">删除</span>   </li>      </div>  </div>     </div> </div>    </div></template><script>import { Toast } from "vant";import { get } from "../../../api/api";export default {    data() { return {     dele_text: {},     profileID: 1,     fileList: [  {      name: "",      size: "",      modificationTime: ""  }     ],     stateObj: {}, //下载进度     downObj: {}, //下载对象     fileObj: [],     downloadimg_item: {},     downloading_pross: {},     downloading: [],     isreset: false,     pross_line: 0,     loading_show: false,     is_downloading: false,     model_state: true };    },    methods: { onClickLeft() {     this.$router.push({  path: "/Navigation"     }); }, to_detail(id) {     this.$router.push({  path: "/index",  query: {      profileId: id  }     }); }, pause(id) {     var that = this;     console.log("login pause");     if (that.downloading_pross[`schedule${id}`] == "继续") {  that.downObj[`dtask${id}`].resume();     } else if (that.downloading_pross[`schedule${id}`] == "重试") {  that.downloading.map((val, index) => {      if (val.downid == id) {   that.downloading.splice(index, 1);      }  });  that.isreset = true;  that.downObj[`dtask${id}`].abort();  that.downFail(id);     } else if (parseInt(that.downloading_pross[`schedule${id}`]) > 0) {  that.downObj[`dtask${id}`].pause();  that.downloading_pross[`schedule${id}`] = "继续";     } }, dele_downing(id) {     var that = this;     plus.downloader.enumerate(e => {  e.map(val => {      if (JSON.parse(val.data).id == id) {   val.abort();      }  });     }, -1);     this.$nextTick(() => {  that.downloading.map((val, index) => {      if (val.downid == id) {   that.downloading.splice(index, 1);   plus.storage.setItem("downing",JSON.stringify(that.downloading)   );      }  });     });     // that.downObj[fileName].start(); }, dele(id, index) {     var that = this;     console.log("进行删除");     var load;     new Promise((resolve, reject) => {  // that.loading_show = true;  load = Toast.loading({      message: "删除中...",      forbidClick: false  });  setTimeout(() => {      resolve();  }, 100);     }).then(() => {  plus.io.resolveLocalFileSystemURL(      "_doc/profile/profile" + id,      e => {   console.log(e.name);   e.removeRecursively(e => {    console.log("删除profile" + id + "成功");    // that.checkFile();    that.fileObj.splice(index, 1);    load.clear();},e => {    console.log("删除profile" + id + "失败");}   );      },      e => {   console.log(`进行删除profile${id}失败`);   console.log(e);      }  );     }); }, down1(num) {     var that = this;     that.downFail(num); }, downFail(id) {     var that = this;     that.$set(that.downloading_pross, "schedule" + id, "正在连接");     that.$set(that.downloading_pross, "prossend" + id, 0);     that.$set(that.downloading_pross, "prossing" + id, 0);     return new Promise((resolve, reject) => {  that.$set(that.downloading_pross, "schedule" + id, "下载中");  console.log("进入下载...");  // that.is_downloading = true;  that.downloadimg_item = {};  that.isreset = false;  that.downloadimg_item.downid = id;  that.downloadimg_item.name =      this.$route.query.name || "下载名称";  that.downloadimg_item.state = 0;  that.downloading.push(that.downloadimg_item);  plus.storage.setItem(      "downing",      JSON.stringify(that.downloading)  );  that.$set(that.downObj, "dtask" + id, 0);  let URL = "需要访问下载的IP地址";  var url =      process.env.NODE_ENV == "development"   ? baseTestURL + "/mobile/offlineDownload/download"   : baseProduceUrl + "/mobile/offlineDownload/download";  console.log(url);  var options = {      method: "POST",      data: JSON.stringify({ id: id }),      filename: `_doc/zips/zip${id}/zip${id}.zip`,      retry: 0  };  var fileName = `dtask${id}`;  that.downObj[fileName] = plus.downloader.createDownload(      url,      options,      function(d, status) {   console.log(d.state);   // 下载完成   if (status == 200) {console.log("Download success: " + d.filename);console.log("下载完成");// that.downloadimg_item[`"schedule${id}"`] =//     "解压中";resolve(id);   } else {console.log("Download failed: " + status);reject(id);   }      }  );  that.downObj[fileName].setRequestHeader(      "Content-Type",      "application/json"  ); // 设置POST请求提交的数据类型为JSON字符串  that.downObj[fileName].setRequestHeader(      "Authorization",      "Bearer " + localStorage.getItem("token")  );  that.downObj[fileName].addEventListener(      "statechanged",      (d, states) => {     if (d.downloadedSize !== 0) {that.downloading_pross[`schedule${id}`] =    "下载中...";// that.$set(that.downloading_pross, "schedule" + id, 123);   }      },      false  );  that.downObj[fileName].start();  plus.storage.setItem("downObj", JSON.stringify(that.downObj));     })  .then(id => {      return new Promise((resolve, reject) => {   plus.io.resolveLocalFileSystemURL("_doc/profile/profile" + id,e => {    console.log(e.name);    console.log( plus.io.convertLocalFileSystemURL(     "_doc/profile/profile" + id )    );    e.removeRecursively( e => {     console.log(  "删除profile" + id + "成功"     );      resolve(id);  }, e => {     console.log(  "删除profile" + id + "失败"     );     resolve(id); }    );},e => {    console.log(`进行删除profile${id}失败`);    console.log(e);    resolve(id);}   );      });  })  .then(id => {      return new Promise((resolve, reject) => {   console.log("进入解压...-----id-----" + id);   plus.zip.decompress(`_doc/zips/zip${id}/zip${id}.zip`,`_doc/profile/profile${id}/`,e => {    console.log("解压完成");    that.downloading_pross[`schedule${id}`] = "删除";    console.log(id);    that.downloading.map((val, index) => { if (val.downid == id) {     that.downloading.splice(index, 1); }    });    plus.storage.setItem( "downing", JSON.stringify(that.downloading)    );    that.checkFile();    resolve(id);},e => {    console.log("解压失败");    reject(id);}   );      });  })  .then(id => {    that.downloadimg_item.state = 1;      return new Promise((resolve, reject) => {   plus.io.resolveLocalFileSystemURL(`_doc/zips/zip${id}`,e => {    console.log(e.name, e.isFile);    e.removeRecursively( e => {     console.log("删除zip" + id + "成功"); }, e => {     console.log("删除zip" + id + "失败"); }    );},e => {    console.log("zip" + id + "删除失败或者不存在");}   );      });  })  .catch(id => {      // that.is_downloading = false;      console.log(`进入catch${id}`);      that.downloadimg_item.state = 1;      that.downloading_pross[`schedule${id}`] = "重试";     plus.io.resolveLocalFileSystemURL(   `_doc/zips/zip${id}`,   e => {e.removeRecursively(e => {    console.log(`删除zip${id}成功`);});   },   e => {console.log(`zip${id}删除失败或者不存在`);   }      );      // that.dele(id);  }); }, checkFile() {     var that = this;     that.model_state = true;     that.fileObj = [];     that.downloading =  JSON.parse(plus.storage.getItem("downing")) || [];     that.downObj = JSON.parse(plus.storage.getItem("downObj")) || [];     plus.io.resolveLocalFileSystemURL("_doc/profile", fs => {  var dirReader = fs.createReader();  dirReader.readEntries(e => {      e.map(val => {   console.log(val.name);   var obj = {};   var fileReader = val.createReader();   fileReader.readEntries(e => {    e.map(val => { console.log(val.name); if (val.isFile) {     console.log("进入json成功");     val.file(  e => {      console.log("正在读取json");      var fileReader = new plus.io.FileReader();      fileReader.readAsText(   e,   "utf-8"      );      //读取完毕      fileReader.onload = e => {   console.log("读取json成功");   var result =e.target.result;   var res = JSON.parse(result   );   // obj.size = res.size;   obj.id = res.id;   obj.name = res.name;   that.fileObj.push(obj);   that.model_state = false;   console.log(JSON.stringify(    that.fileObj)   );      };  },  e => {      console.log("读取json文件失败");  }     );     // } else {     console.log("未检索到json文件"); }    });},e => {    console.log(val.name + "读取失败");}   );      });  });     }); }    },    filters: { getSize: function(value) {     if (value < 1000000) {  var num = (value / 1000).toFixed(2);  var firstNum = num.split(".")[0];  var lastNum = num.split(".")[1];  if (lastNum > 10 && lastNum % 10 == 0) {      // if (lastNum % 10 == 0 && lastNum / 10 !== 0) {      //50      return firstNum + "." + lastNum[0];  } else if (lastNum == 0) {      //00      return firstNum + "MB";  } else {      return num + "MB";  }     } else {  var num = (value / 1000000).toFixed(2);  var firstNum = num.split(".")[0];  var lastNum = num.split(".")[1];  if (lastNum > 10 && lastNum % 10 == 0) {      // if (lastNum % 10 == 0 && lastNum / 10 !== 0) {      //50      return firstNum + "." + lastNum[0] + "GB";  } else if (lastNum == 0) {      //00      return firstNum + "GB";  } else {      return num + "GB";  }     } }    },    mounted() { var that = this; // console.log(this.$route.query); // console.log(localStorage.getItem("token")); if (this.$route.query.id) {     console.log(this.$route.query.id);     that.profileID = this.$route.query.id;     that.downFail(this.$route.query.id); } else {     console.log("进入检查");     that.checkFile(); }    }};</script><style lang="less" scoped>li {    list-style: none;}.wrapper {    display: flex;    align-items: center;    justify-content: center;    height: 100%;}.pross {    text-align: center;}.download_body {    display: flex;    justify-content: space-between;}.enpty_box {    text-align: center;}.down_item {    background-color: rgb(243, 243, 243);    display: flex;    justify-content: space-between;    margin: 10px 0;    padding: 5px 20px;    .down_item_left { width: 50vw; display: flex; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; word-break: break-all; li {     display: flex;     font-size: 16px;     i {  color: green;     } }    }    .down_item_right { display: flex; align-items: center; justify-content: center; li {     display: flex;     .downloading_icon {  display: flex;  margin-right: 15px;     }     span:last-child {  margin-left: 5px;     } }    }}.downend_box {    li { margin: 10px 0; background-color: rgb(243, 243, 243); padding: 5px 20px; display: flex; justify-content: space-between; span {     margin: 3px 0; } span:first-child {     width: 50vw;     overflow: hidden;     text-overflow: ellipsis;     display: -webkit-box;     -webkit-box-orient: vertical;     -webkit-line-clamp: 1;     word-break: break-all;     display: flex;     font-size: 16px;     line-height: 30px;     i {  margin-right: 3px;  color: aqua;     } } span:last-child {     display: flex;     color: rgb(164, 190, 166);     font-size: 13px;     align-items: center; }    }}.wrapper {    display: flex;    flex-direction: column;    li:last-child { padding-top: 20px;    }}</style><style lang="less">.download_head_tabbar {    .van-nav-bar .van-icon { color: #000;    }}</style>