h5的app需求
在各种需求中 大致有两类
- 让h5直接运行成app,有一个成熟的h5项目,想直接打包app
- 不想触发app更新,又能获取最新的更新效果,使用webview套h5,最终生成app
今天笔者带大家粗略实现以上的两个需求
h5直接打包app 使用hbuiderx帮助
- 打开hbuiderx 新建项目 选择 5+app
- 删除其他的多余文件 将自己打包生成的文件进行替换
- 一般vue和react生成打包的项目也是这种结构 引入进去 然后manifest去引入自己需求的app图标就行了
这种比较简单粗暴 但涉及一些app的扫码拍照之类 就需要自行寻找 5+的api进行集成了
使用uniapp 将h5链接接入进来
笔者之前帮一所大学做过类似的app 有的需求就是不想要频繁更新 去下载各个版本的app,所有想采用 h5的更新方式 更加方便快捷
搭建app框架
1 新建一个uniapp项目 就默认模板就行
2 删除pages/index/index里的内容 添加你的webview代码进去
3 pages/index/index 添加对应代码
<view class="content"><web-view :src="webviewUrl"@message="handleMessage" ref="webview" ></web-view></view>
handleMessage(evt) {console.log('接收到的消息:' + JSON.stringify(evt.detail.data));}
- 4 页面获取webview实例 主动调取对应的H5方法
<script>var wv; //计划创建的webviewexport default {data() {return {canBack: false,isExit: true, // 是否退出webviewUrl: 'http://192.168.101.129:9000/" />, // 本地 }},onReady() {// #ifdef APP-PLUS//如果是页面初始化调用时,需要延时一下var self = this;var currentWebview = this.$scope.$getAppWebview(); //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效,非v3编译模式使用this.$mp.page.$getAppWebview()setTimeout(function() {wv = currentWebview.children()[0];wv.addEventListener('progressChanged',function(e) {wv.canBack(function(e) {self.canBack = e.canBack;});wv.evalJS('goBack()') // 主动调取 H5的函数 (H5需要把交互的方法挂载到window上给app使用)},false);}, 500); // #endif},}<script>
这样其实就算勉强完成app的功能了
搭建h5的页面
这里可以使用单页面应用 多页面应用 看大家自己选择 不过现在都是vue或者react直接写会比较快 操作方式都是一样的
h5页面引入 uni.webview.1.5.4.js
这一部分主要使得 h5页面可以和app产生桥梁 互相通信
这里有官方的一些链接 uni官方webview文档
下载 uni.webview.1.5.4.js到你的h5入口文件
放入入口文件 index.html
这里用vue项目举例 其他的框架举一反三即可
- 1 将下载好的 js放入一个文件夹 我这里命名sdk 按照图中的引入方式进行对应的增添代码
- 2 去页面中执行对应的代码 如果你想监听是否引入成功 可以在h5项目 任意js逻辑部分 写下如下代码
document.addEventListener('UniAppJSBridgeReady', function(e) {uni.getEnv(function(res) {console.log('当前环境:' + JSON.stringify(res));});// 向uniapp底座发送消息uni.postMessage({data: 'H5发送的消息'});});
不难看出 uni.postMessage 就是H5向uniapp底座发送的消息 uniapp通过handleMessage去接受 看上面app部分即可
- 3 注册函数给uniapp使用 uniapp可以通过实例直接调用 对应方法 如: wv.evalJS(‘goBack()’)
我是在App,vue里注册的 便于集中管理
其实这样 一个简单的H5和uniapp就可以结合在一起 进行组合开发了
优化
解决物理返回键和H5页面的路由跳转问题
不难看出 我们只是在uniapp配置的入口页面引入了 H5页面来进行业务类型开发
那么H5页面本身是有路由页面切换的 但是如果采用手机本身的物理返回键 直接会退出整个应用
那么 如何去规避这个问题?让返回键也跟随H5的页面栈返回呢?
1 首先 uniapp的页面是有 onBackPress 这个钩子函数 正好来捕捉物理返回键的调用 和其他一切触发返回的操作
当它 return true 返回的操作将会失效2 我们可以在 uniapp的页面的data中定义一个是否 变量isExit 来判断是否调用真实返回退出的操作 如果是H5页面非首页内的切换后退 不会触发uniapp的返回退出操作
H5页面去做相关判断 如果是跳转其他页面和首页给uniapp底座发送不同消息 让app判断 isExit 具体为true还是false
webview缓存解决方案
其实webview在使用线上的链接时 是会存在缓存的 解决方案 很简单给链接拼接一个时间戳或者随机数的方式 实现每次访问不同的链接 清理缓存
但是缓存有时候又是很必要的 这就需要去考虑是否需要每时每刻刷新了
我是将他存入缓存 需要更新时去除这个缓存 重新进应用就会再次获取一个随机数 去清除缓存的
let randomNum = uni.getStorageSync('randomNum')if (!randomNum) {randomNum = Math.ceil(Math.random() * 1000000000);uni.setStorageSync('randomNum', randomNum);}this.webviewUrl = this.webviewUrl + randomNum;