web app升级—带进度条的App自动更新
带进度条的App自动更新,效果如下图所示:

技术:vue、vant-ui、5+
封装独立组件AppProgress.vue:
<template>
<div>
<van-dialog
v-model="showProgress"
confirm-button-text="后台下载"
class="app-update"
@confirm="confirmClick"
>
<img src="../../assets/imgs/progress-bar.png" />
<van-progress :percentage="percentageVal" />
<div class="msg">版本更新中,请稍后...</div>
</van-dialog>
</div>
</template> <script>
// app下载进度组件
export default {
props: {
// 进度值
percentageVal: {
type: Number,
default: 0
},
// 是否显示弹窗
showProgress: {
type: Boolean,
default: false
}
},
data() {
return {}
},
methods: {
confirmClick() {
this.$emit('confirm');
}
}
}
</script> <style lang="scss" scoped>
img {
width: 270px;
height: 163px;
position: fixed;
top: -35px;
z-index: 2200;
}
</style>
<style lang="scss">
.app-update.van-dialog {
overflow: visible;
width: 270px;
border-radius: 12px;
.van-progress {
margin-top: 124px;
z-index: 2300;
}
.msg {
font-size: 16px;
font-weight: 600;
color: white;
position: absolute;
top: 50px;
z-index: 2300;
width: 100%;
text-align: center;
}
.van-dialog__footer {
border-radius: 12px;
.van-button--default {
.van-button__text {
width: 105px;
height: 26px;
border-radius: 13px;
background-color: #006eff;
color: white;
font-weight: 600;
font-size: 12px;
display: inline-block;
margin-top: 10px;
line-height: 26px;
}
}
}
}
</style>
app升级代码,封装独立js文件:appUpdateOptions.js
/**
* IOS 包发布到应用市场后要更新此处的ID,替换掉测试ID:1053012308
*/
/* eslint-disable no-undef */
import { getVersion } from '@/services/login';
import request from '../../api/ajax.js';
import { Dialog } from 'vant';
import expiredStorage from '@/utils/expiredStorage.js'; function sleep(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime) return;
}
} // Vue继承的基础对象
export default {
data() {
return {
showProgress: false,
percentageVal: 0
};
},
methods: {
appUpdate(ismanual) {
const that = this;// 获取5+运行环境的版本号
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
const ver = inf.version;var ua = navigator.userAgent.toLowerCase();
// 苹果手机
if (/iphone|ipad|ipod/.test(ua)) {
// 获取当前上架APPStore版本信息
request
.get('https://itunes.apple.com/lookup?id=1053012308', {
id: 1053012308 // APP唯一标识ID
})
.then(data => {
console.log('data:' + JSON.stringify(data));
var resultCount = data.resultCount;
for (var i = 0; i < resultCount; i++) {
var normItem = data.results[i].version;if (normItem > ver) {
var _msg = '发现新版本:V' + normItem;
// plus.nativeUI.alert("发现新版本:V" + normItem);
Dialog.confirm({
title: '升级确认',
message: _msg
})
.then(() => {
// on confirm
// 执行升级操作
document.location.href =
'https://itunes.apple.com/cn/app/id1053012308?mt=8'; // 上新APPStore下载地址
})
.catch(() => {
// on cancel
expiredStorage.setItem('$upgradeTip', false, 1 / 12); // 1/12天内不再显示升级提示
});
return;
}
}
if (ismanual) {
plus.nativeUI.toast('当前版本号已是最新');
}
});
} else if (/android/.test(ua)) {
getVersion().then(res => {if ((res.code = 200 && res.data.version > ver)) {
var _msg = '发现新版本:V' + res.data.version;
const apkUrl = res.data.redirectUrl;
Dialog.confirm({
title: '升级确认',
message: _msg
})
.then(() => {
// on confirm
that.showProgress = true;
var dtask = plus.downloader.createDownload(
apkUrl,
{},
function(d, status) {
if (status == 200) {
// sleep(1000);
var path = d.filename; // 下载apk
plus.runtime.install(path); // 自动安装apk文件
that.showProgress = false;
} else {
plus.nativeUI.alert('版本更新失败:' + status);
that.showProgress = false;
}
}
);
try {
dtask.start(); // 开启下载的任务
var prg = 0;
dtask.addEventListener('statechanged', function(
task,
status
) {
// 给下载任务设置一个监听 并根据状态 做操作
switch (task.state) {
case 1:
//'正在下载';
break;
case 2:
// '已连接到服务器';
break;
case 3:
prg = parseInt(
(parseFloat(task.downloadedSize) /
parseFloat(task.totalSize)) *
100
);
that.percentageVal = prg;
break;
case 4:
that.showProgress = false;
break;
}
});
} catch (err) {
that.showProgress = false;
if (ismanual) {
plus.nativeUI.toast('网络异常,请稍候再试' + err);
}
}
})
.catch(error => {
// on cancel
that.showProgress = false;
expiredStorage.setItem('$upgradeTip', false, 1 / 12); // 1/12天内不再显示升级提示
});
} else {if (ismanual) {
plus.nativeUI.toast('当前版本号已是最新');
}
}
});
}
});
},
// 点击确定按钮
confirmClick() {
this.showProgress = false;
}
}
};
注意:这里的版本号以字符串比较的方式可能会出现问题,正确的方式应该是:
function compareVersion(v1, v2) {
v1 = v1.split('.')
v2 = v2.split('.')
var len = Math.max(v1.length, v2.length)
while (v1.length < len) {
v1.push('0')
}
while (v2.length < len) {
v2.push('0')
}
for (var i = 0; i < len; i++) {
var num1 = parseInt(v1[i])
var num2 = parseInt(v2[i])
if (num1 > num2) {
return 1
} else if (num1 < num2) {
return -1
}
}
return 0
}
compareVersion('1.11.0', '1.9.9') // => 1 // 1表示 1.11.0比1.9.9要新
compareVersion('1.11.0', '1.11.0') // => 0 // 0表示1.11.0和1.11.0是同一个版本
compareVersion('1.11.0', '1.99.0') // => -1 // -1表示1.11.0比 1.99.0要老
调用代码:
import appUpdateOptions from '@/utils/mixins/appUpdateOptions.js'
import AppProgress from '@/components/common/AppProgress.vue';
export default {
components: { AppProgress },
props: {},
mixins: [appUpdateOptions],
methods: {
// app更新
appUpdateFuc() {
const that = this;
that.$mui.plusReady(function() {
that.appUpdate(true);
});
},
结束.......
web app升级—带进度条的App自动更新的更多相关文章
- 自定义带进度条的WebView , 增加获取web标题和url 回掉
1.自定义ProgressWebView package com.app.android05; import android.content.Context; import android.graph ...
- web文件上传,带进度条
原生ajax上传带进度条 (百分比) <%@ page language="java" contentType="text/html; charset=UTF-8& ...
- 【Web】前端文件上传,带进度条
最近做项目发现,在文件上传的过程中,增加进度条,能大大改善用户体验.本例介绍带进度条的文件上传 环境搭建 参考:[Java]JavaWeb文件上传和下载. 原生ajax上传带进度条 <%@ pa ...
- Android更新带进度条的通知栏
在网上查询了下.Android版本号更新通知栏带进度条,醉了,基本都是复制过来.有的代码不全,连源代码下载都没有.有下载也须要积分,还不能用,真黑心啊!!之前自己也写过自己定义通知栏Notificat ...
- Android -- 自定义带进度条的按钮
1. 实现了一个带进度条的按钮,完成后显示提示信息,并设置按钮为不可再次被点击
- wxpython StatuBar 带进度条的状态栏
# -*- coding: utf- -*- import wx class customStatusBar(wx.StatusBar): def __init__(self, parent): wx ...
- 025 Android 带进度条的对话框(ProgressDialog)
1.ProgressDialog介绍 ProgressDialog可以在当前界面弹出一个置顶于所有界面元素的对话框,同样具有屏蔽其他控件的交互能力,用于提示用户当前操作正在运行,让用户等待: 2.应用 ...
- java进行文件上传,带进度条
网上看到别人发过的一个java上传的代码,自己写了个完整的,附带源码 项目环境:jkd7.tomcat7. jar包:commons-fileupload-1.2.1.jar.commons-io-1 ...
- atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7
atitit.文件上传带进度条的实现原理and组件选型and最佳实践总结O7 1. 实现原理 1 2. 大的文件上传原理::使用applet 1 3. 新的bp 2 1. 性能提升---分割小文件上传 ...
随机推荐
- [CF1082D]Maximum Diameter Graph
题目描述 Description Graph constructive problems are back! This time the graph you are asked to build sh ...
- onload()方法只能在body标签中调用吗?怎么调用多个多个方法?
第一个问题: onload()方法并非只能在body标签中调用的,还可以在js中用window.onload = function() {函数名};来调用:另外img等标签也支持onload方法. 支 ...
- .NET Core 中读取 Request.Headers 的姿势
Request.Headers 的类型是 IHeaderDictionary 接口,对应的实现类是 HeaderDictionary ,C# 实现源码见 HeaderDictionary.cs . H ...
- IT兄弟连 Java语法教程 数据类型2
整型 Java定义了4种整数类型:byte.short.int和long.所有这些类型都是有符号的.正或负的整数.Java不支持无符号的.只是正值的整数.许多其它计算机语言同时支持有符号和无符号整数. ...
- P站全新官方精选集Pixivision
P站是一个主要由日本艺术家所组成的虚拟社群,主打插画.漫画.二次元作品网上沟通. 不过好消息是,P站全新的精选网站Pixivision上线了,多种语言界面,国内用户访问毫无压力. 近期精选的一系列作品 ...
- .NET Core CSharp初级篇 1-2 循环与判断
.NET Core CSharp初级篇 1-2 本节内容循环与判断 循环 循环是一个在任何语言都是极为重要的语法,它可以用于很多东西,例如迭代数组等等.在C#中,语法层面的循环有:for , fore ...
- JVM中优化指南
JVM中优化指南 如何将新对象预留在年轻代 如何让大对象进入年老代 如何设置对象进入年老代的年龄 稳定的 Java 堆 VS 动荡的 Java 堆 增大吞吐量提升系统性能 尝试使用大的内存分页 使用非 ...
- Dynamics 365 We API ODATA语法根据父记录查询子记录,根据子记录查询父记录(附上根据团队,队列名称查成员)
微软动态CRM专家罗勇 ,回复333或者20190508可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 先举个N:N关系的例子.这里以根据团队的名称查找其所有团队成员的 ...
- 【微信小程序】e.currentTarget和e.target
什么是事件 事件是视图层到逻辑层的通讯方式. 事件可以将用户的行为反馈到逻辑层进行处理. 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数. 事件对象可以携带额外信息,如 id ...
- 74HC245引脚定义 使用方法
典型的CMOS型三态缓冲门电路,八路信号收发器. 由于单片机或CPU的数据/地址/控制总线端口都有一定的负载能力,如果负载超过其负载能力,一般应加驱动器. 主要应用于大屏显示 引脚定义 DIR:方向控 ...