• uniApp实现热更新


    热更新

    热更新是开发中常见且常用的一种软件版本控制的方式,在uniapp进行使用热更新将软件实现更新操作
    思路:

    • 服务器中存储着最新版本号,前端进行查询
    • 可以在首次进入应用时进行请求版本号进行一个匹对
    • 如果版本号一致则不提示,反之则提示进行更新执行更新操作

    实现

    采用方法封装进行使用~

    1.封装一个对比版本号的函数

    /**
     * 对比版本号,如需要,请自行修改判断规则
     * 支持比对	("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")	("3.0.0.1", "3.0")	("3.1.1", "3.1.1.1") 之类的
     * @param {Object} v1
     * @param {Object} v2
     * v1 > v2 return 1
     * v1 < v2 return -1
     * v1 == v2 return 0
     */
    function compare(v1 = '0', v2 = '0') {
    	v1 = String(v1).split('.')
    	v2 = String(v2).split('.')
    	const minVersionLens = Math.min(v1.length, v2.length);
    
    	let result = 0;
    	for (let i = 0; i < minVersionLens; i++) {
    		const curV1 = Number(v1[i])
    		const curV2 = Number(v2[i])
    
    		if (curV1 > curV2) {
    			result = 1
    			break;
    		} else if (curV1 < curV2) {
    			result = -1
    			break;
    		}
    	}
    
    	if (result === 0 && (v1.length !== v2.length)) {
    		const v1BiggerThenv2 = v1.length > v2.length;
    		const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
    		for (let i = minVersionLens; i < maxLensVersion.length; i++) {
    			const curVersion = Number(maxLensVersion[i])
    			if (curVersion > 0) {
    				v1BiggerThenv2 ? result = 1 : result = -1
    				break;
    			}
    		}
    	}
    	return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    1. 封装更新函数

    通过downloadTask.onProgressUpdate进行监听,再通过plus.nativeUI.showWaiting("正在下载 - 0%"); 进行加载显示下载进度…

    var updateUseModal = (packageInfo) => {
    	const {
    		title, // 标题
    		contents, // 升级内容
    		is_mandatory, // 是否强制更新
    		url, // 安装包下载地址
    		platform, // 安装包平台
    		type // 安装包类型
    	} = packageInfo;
    
    	let isWGT = type === 'wgt'
    	let isiOS = !isWGT ? platform.includes('iOS') : false;
    	let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'
    
    	return uni.showModal({
    		title,
    		content: contents,
    		showCancel: !is_mandatory,
    		confirmText,
    		success: res => {
    			if (res.cancel) return;
    
    			// 安装包下载
    			if (isiOS) {
    				plus.runtime.openURL(url);
    				return;
    			}
    			let waiting =  plus.nativeUI.showWaiting("正在下载 - 0%");  
    			// uni.showLoading({
    			// 	title: '安装包下载中'
    			// });
    			// wgt 和 安卓下载更新
    			const downloadTask = uni.downloadFile({
    				url,
    				success: res => {
    					if (res.statusCode !== 200) {
    						console.error('下载安装包失败', err);
    						return;
    					}
    					// 下载好直接安装,下次启动生效
    					plus.runtime.install(res.tempFilePath, {
    						force: false
    					}, () => {
    						uni.hideLoading()
    						if (is_mandatory) {
    							//更新完重启app
    							plus.runtime.restart();
    							return;
    						}
    						uni.showModal({
    							title: '安装成功是否重启?',
    							success: res => {
    								if (res.confirm) {
    									//更新完重启app
    									plus.runtime.restart();
    								}
    							}
    						});
    					}, err => {
    						uni.hideLoading()
    						uni.showModal({
    							title: '更新失败',
    							content: err.message,
    							showCancel: false
    						});
    					});
    				},
    				//接口调用结束
    				complete: ()=>{
    					uni.hideLoading();
    					downloadTask.offProgressUpdate();//取消监听加载进度
    				}
    			});
    			//监听下载进度
    			downloadTask.onProgressUpdate(res => {
    				// state.percent = res.progress;
    				waiting.setTitle("正在下载 - "+res.progress+"%");
    				// console.log('下载进度百分比:' + res.progress); // 下载进度百分比
    				// console.log('已经下载的数据长度:' + res.totalBytesWritten); // 已经下载的数据长度,单位 Bytes
    				// console.log('预期需要下载的数据总长度:' + res.totalBytesExpectedToWrite); // 预期需要下载的数据总长度,单位 Bytes
    			});
    		}
    	});
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    1. 用变量接收实现函数(在函数中使用上方封装的函数)并导出

    fRequestWithToken为我封装的请求方法,可自行进行使用axios进行请求也行!!!

    var fCheckVersion = (cb) => {
    	// #ifdef APP-PLUS
    	plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {
    		// console.log(widgetInfo.version)
    		// console.log(plus.runtime.version)
    		// console.log(widgetInfo.version)
    		var nVerSta = compare(plus.runtime.version, widgetInfo.version),
    			sLaststVer = plus.runtime.version;
    		if (widgetInfo.version) {
    			if (nVerSta == 1) {
    				console.log(plus.runtime.version)
    				sLaststVer = plus.runtime.version
    			} else if (nVerSta == -1) {
    				console.log(widgetInfo.version)
    				sLaststVer = widgetInfo.version
    			}
    		}
    		console.log(sLaststVer)
    		//发送请求进行匹对,我这里数据库设定的是如果返回null则版本号一致,反之需要更新!!!
    		fRequestWithToken({
    			ajaxOpts: {
    				url: URLS_COM.d_lastVer,
    				data: {
    					versionCode: sLaststVer
    				}
    			},
    			showloading: false,
    			silence:true
    		}).then(data => {
    			console.log(data)
    			// console.log('################')
    			if (data) {
    				var sUrl = '',
    					type = '';
    				if (data.wgtName) {
    					sUrl = data.wgtName;
    					type = "wgt"
    				} else {
    					sUrl = data.pkgName;
    					type = "pkg";
    				}
    
    				updateUseModal({
    					title: data.title||"",
    					contents: data.note||'',
    					is_mandatory: true,
    					url: sUrl,
    					platform: 'android',
    					type: type // 安装包类型
    				})
    			}
    		}).catch((res)=>{
    			cb&&cb()
    			console.log(res)
    		})
    	})
    	// #endif
    }
    
    export {
    	fCheckVersion
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    以上代码即可实现热更新的操作

    使用

    可在App.vue中进行使用,根据项目需求而定

    1.引入封装好的函数

    路径自己记得填写自己封装的位置

    import{fCheckVersion} from '@/common/project/checkversion.js'
    
    • 1

    2.然后可以在onLoad函数中进行触发

    onLoad() {
    		fCheckVersion();//检查更新
    }
    
    • 1
    • 2
    • 3

    这样就实现了热更新
    然后的话只需要进行打包个热更新的包
    在这里插入图片描述
    后端进行上传至服务器进行更新数据
    本地再进行一个云打包,记得在mainifest.json文件中进行版本号的修改,修改成低于热更新包的版本号即可

    在这里插入图片描述
    这样就ok了,实用✌!(别盗我文章😫)

  • 相关阅读:
    基于java+springboot+vue实现的高校社团管理系统(文末源码+Lw+ppt)23-419
    异步过渡方案—Generator
    Python制作炫酷的个人足迹地图
    Electron:窗口、窗口标题和边框
    算法金 | 决策树、随机森林、bagging、boosting、Adaboost、GBDT、XGBoost 算法大全
    基于Delta Lake构建数据湖仓体系
    从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(十一)spring-boot-admin 监控篇(1) 原理与介绍
    【GA+RBF+channel】基于遗传优化RBF的信道估计均衡算法matlab仿真
    【Linux】服务器恶意登录记录及解决方案
    JS基础6--逻辑运算符
  • 原文地址:https://blog.csdn.net/m_xiaozhilei/article/details/126485684