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>