发布时间:2023-05-23 文章分类:WEB开发, 电脑百科 投稿人:李佳 字号: 默认 | | 超大 打印

为了减少app频繁上架,频繁更新,决定放弃纯uniapp开发,改用uniapp(后续简称uni)+h5的方式进行混合开发。
技术选型:
整个app架子用uni(vue3),h5采用vue3+vant4,然后使用uni的webview进行页面控制。由于我们是由vue2升级到vue3,所以之前的一些代码需要做调整,这里自己去看一下vue2和vue3的区别。在技术选型上也本着一个原则,如遇技术冲突,就以uniapp为主,h5只做页面展示。
其中还有几个点在这次升级中也提出来了,考虑到篇幅问题,这里只贴关键代码
1、页面跳转问题,uni有路由管理,h5也有路由管理,由于所有的h5界面都采用web-view方式访问,所以h5界面在开发的时候规定了不允许使用window.open(在ios系统中有可能出现无法使用的情况)和location.href方式跳转,也禁用了h5的路由方式跳转,代码如下:

//uni获取webview访问路径
//该页面名称vuePage
<template>
	<view>
		<web-view :src="indexUrl" @message="getMessage" @onPostMessage="getPostMessage">
		</web-view>
	</view>
</template>
onLoad(param) {
			let _this = this
			let url=decodeURI(param.vuePage)
			url=base64.decode(url);
			//"/app_dyg"+url 前端路由地址
			_this.indexUrl = '前端访问地址'+"/app_dyg"+url
		},
/**
 * 保留当前页面,跳转到vue界面,这种方式不需要全路径,只需要页面的路由
 * @param url
 */
const navigateToVueView = (url) => {
  url = Base64.toBase64(url)
  window.uni.webView.navigateTo({
    url: '../vuePage/vuePage?vuePage=' + encodeURI(url)
  })
}

这种方式就是h5界面调用uni提供的路由跳转接口进行页面跳转,需要注意的是h5界面需要引入uni.webview.1.5.2.js,具体引入方式可参考官方文档,就不过多赘述。这里只列举了一种,如有其他需要可参考这段代码进行编写,下图是uni提供的部分接口
uniapp+h5混合开发
2、页面返回之后h5界面没有刷新数据问题
由于所有的h5界面都是采用的webview方式访问的,页面都是存在uni页面栈里面的,所以返回之后h5的勾子函数会失效,但是uni的onShow()是有效的,所以在页面返回之后通过evalJS传值的方式来触发h5页面的刷新,代码如下:

onShow() {
			// #ifdef APP-PLUS
			if(typeof this.$mp!='undefined' && typeof this.$mp.page!='undefined'){
				var currentWebview = this.$mp.page.$getAppWebview();
				var wv = currentWebview.children()[0]
				if (typeof wv != 'undefined') {
					setTimeout(function() {
						wv.evalJS('appMsg()')
					}, 50);
				}
			}
			// #endif
		},

由于appMsg使用频率较高,为了方便使用,我将它注册到了window下面,方便在开发过程中进行调用

//将appMsg注册到window下面
declare interface Window {
  uni: any
  tracking: any
  appMsg: any
}
//在需要刷新数据的界面进行调用
window.appMsg = () => {
  getData()
}

3、重要信息缓存问题
在使用过程中,我们会将用户信息,token等重要信息缓存起来,尤其是token这种数据,生命周期比较短,在我们系统中只有5分钟,就需要在uni不断的刷新token,如果多端进行数据维护也比较麻烦,所以在开发过程中h5端只调用uni缓存的信息,代码如下

if (window.plus) {
            setData();
        } else {
            document.addEventListener('plusready', setData, false);
        }
        function setData() {
            sessionStorage.setItem('token', plus.storage.getItem('token'))
            sessionStorage.setItem('userInfo', plus.storage.getItem('user'))
            sessionStorage.setItem('appApiUrl', plus.storage.getItem('appApiUrl'))
        }

uni访问h5界面的时候都会触发该方法,所以h5界面会将uni缓存的最新数据进行存储,保证数据的一致性。这里在开发过程中遇到这样一个问题,目前主要是ios系统中发现了这个问题,就是数据缓存和页面加载不同步,也就是页面加载完了,但是token等数据还没有缓存好,所以在h5的路由配置的时候是做了一个延迟加载的处理

router.beforeEach((to: any, from, next) => {
  if (to.meta.title) {
    document.title = to.meta.title
  }
  if (to.matched.length === 0) {
    next('/404')
  } else {
    setTimeout(function () {
      next()
    }, 300)
  }
})