(本文仅针对使用微信小程序官方tabbar的情形)
1、需求分析
一般来说,小程序底部tabbar点击激活都是使用原生页面,这样切换效果好。但就是有些特殊的需求要使用h5页面来承载tabbar的激活页。
由于h5需要使用webview页,而小程序webview打开就是铺满整个屏幕容器,且无法被其他元素覆盖层级,所以是无法做到tabbar和webview同时展示的,只能跳转一下。
2、处理点
- tabbar激活页只需要一个空内容,不做任何展示,进入后就通过js跳转到相应的webview页,这样你一点击tabbar加载完看到的就是webview页内容了。
- 在webview页,返回时需要返回上一个tabbar页。
3、具体实现
(1)入口文件app.js
首先在globalData里添加两个字段:
globalData: {originalTab: '', // 记录原始tab栏激活位置,用于h5类型的tabbar页返回跳转isBackOriginalTab: false, // 控制是否是要返回上一个tabbar页
}
然后添加一个公共方法:
// 设置originTab数据setOriginTab (tabPath) {this.globalData.originalTab = tabPaththis.globalData.isBackOriginalTab = false},
(2)tabbar原生页
在所有非webview类型的tabbar原生激活页里,onShow生命周期方法里调用setOriginTab,传入当前页路径:
// 以首页index为例 (const app = getApp())
onShow() {app.setOriginTab('/pages/index/index')
}
这样每进入一次tabbar激活页就保存了当前页的路径到全局数据中了,便于后续从webview页返回时选择要返回哪一个tabbar页。
(3)webview页
小程序的webview页建议统一一下,能共用一个路径就共用,便于维护。
在你的webview页的onUnload生命周期方法里添加代码:
// (const app = getApp())
onUnload () {app.globalData.isBackOriginalTab = true
},
(4)tabbar webview类型页
也就是一个空页面,主要代码都在js逻辑处理上。
wxml文件放一个view标签,不需要内容:
<view class="webviewTab"></view>
js文件:
const app = getApp()
const gData = app.globalDataComponent({data: {},methods: {onLoad () {},onShow () {// 判断进入场景if (!gData.isBackOriginalTab) {// 刚进入tab,页面初次加载wx.showLoading({ title: '加载中...' })// 跳转webview页const myUrl = encodeURIComponent('https://m.baidu.com')wx.navigateTo({url: '/pages/webview/index?url=' + myUrl,success() {wx.hideLoading()}})} else {// 从webview页返回回来const tabPath = gData.originalTab// 跳回原tab页wx.switchTab({url: tabPath,})}},}
})
4、总结思路
用两个全局变量存储状态:
一个存储原tabbar页路径,用于从webview页返回跳转,在进入非webview类型的tabbar激活页时在onShow方法里存储;
一个存储进入tabbar激活页的类型,区分是要进入webview还是从webview页返回回来,从webview返回回来会触发webview页的onUnload生命周期钩子,在这里改变存储的值,而在进入非webview类型的tabbar激活页时再重置这个值为默认值,这样就能判断区分了。