最近开发需求微信小程序,被安排了一个需求调整,当在小程序首页进行某些操作从页面底部弹出popup
弹窗框时,需要隐藏首页的tabbar。
基本交互描述
点击首页的按钮,从底部弹出popup A弹窗。点击弹窗左边的分享按钮,会关闭当前的的popup A再弹出一个从底部弹出的popup B,新的popup B有两个分享按钮,点击分享关闭当前弹窗。如点击弹窗右边的【按钮】,则是跳转到另一页面,也关闭弹窗。没有展示底部弹出的popup时,tabbar正常展示,若是popup从底部弹出则隐藏tabbar。
实现思路与具体实现步骤
开发中使用的UI框架为 uviewui 1.x
基本代码结构
<template>
<button @click="makePopShow">按钮</button>
<u-popup v-model="showPopA" mode="bottom" @close="closeFunPop()">
<view class="u-flex u-row-around">
<button type="primary" @click="showSharePop">
<u-icon name="share-fill" size="48"><u-icon>
</button>
<button @click="goNext"></button>
</view>
</u-popup>
<u-popup v-model="showPopB" mode="bottom" @close="closeFunPop()">
<view class="u-flex u-row-around">
<button type="primary" open-type="share">
<u-icon name="share-fill" size="48"><u-icon>
</button>
<button type="primary" open-type="share">
<u-icon name="share-fill" size="48"><u-icon>
</button>
</view>
</u-popup>
</template>
<script>
export default {
data() {
return {
showPopA: false,
showPopB: false
}
},
methods: {
hideTabBar() {
uni.hideTabBar({ animation: true });
},
makePopShow() {
this.hideTabBar();
setTimeout(() => {
this.showPopA = true;
}, 100)
},
closeFunPop() {
console.log('close');
uni.showTabBar({ animation: true });
this.showPopA = false;
this.showPopB = false;
},
showSharePop() {
this.showPopA = false;
this.hideTabBar();
setTimeout(() => {
this.showIviteNextPop = true;
}, 100)
},
goNext() {
let url = '/pages/next/index'
uni.navigateTo({
url,
success: () => {
console.log('start')
uni.showTabBar({ animation: true });
console.log('end')
}
})
},
}
}
</script>
场景
点击页面按钮,弹出popup A
,此时下一步进行:直接关闭popup A
、点击popup A内部右边的按钮
、点击popup A内部左边分享按钮弹出新的popup
-
直接关闭popup A
-
点击popup A右边的【按钮】
点击右边的【按钮】,会跳转到新的页面,但是单返回首页会发现tabbar依旧是隐藏的。查看小程序开发者工具的控制台,调用
goNext
方法时,控制台打印了'start'
与'end'
,说明uni.showTabBar({ animation: true })
执行了;目前无法定位到原因,那么就想其他法子解决问题,毕竟需求有deadline。查看文档,uni-app页面生命周期
在uni-app微信小程序首页的onShow
生命周期,调用uni.showTabBar({ animation: true })
,这样当我们调用goNext
方法,再返回到首页就会正常的展示tabbar。
onShow() {
uni.showTabBar({ animation: true });
}
体验的时候会发现解决上一个问题又会带来新的问题。问题就是每次进入首页都会执行uni.showTabBar({ animation: true })
,导致进入首页就会底部tabbar明显有uni.showTabBar
的动画效果,接下来看看如何优化。优化的关键点:“页面的onShow
生命周期内,只有当小程序tabbar为隐藏状态,才调用uni.showTabBar({ animation: true })
,其他情况不做处理”。
onShow() {
const systemInfo = uni.getSystemInfoSync();
const tabBarHeight = systemInfo.screenHeight - systemInfo.windowHeight - systemInfo.statusBarHeight;
const isTabBarHidden = tabBarHeight <= 0;
if (isTabBarHidden) {
uni.showTabBar({ animation: true });
}
}
通过在首页获取系统信息systemInfo,通过screenHeight - windowHeight - statusBarHeight
的差值,判断tabbar是否隐藏。需要注意的是:在我使用微信开发者工具(1.06.2301040 Stable),即使从首页点击Popup A的右边按钮跳转跳转到新的页面,然后返回首页的tabbar为隐藏状态tabBarHeight的值依然大于0。但是我在真机测试下,结果如下:
机型 | 微信版本 | tabBarHeight的值 |
---|---|---|
三星 SM-G9910 Android 13 | Version 8.0.32 | 小于0 |
Iphone 6s IOS 14.6 | Version 8.0.7 | 小于0 |
经过真机测试,验证优化onShow
生命周期内执行uni.showTabBar({ animation: true })
的时机调整大概率是可行的。
- 点击popup A左边的分享按钮
流程如下:调用showSharePop,关闭upopp A;隐藏tabbar; 显示关闭upopp B
showSharePop() {
this.showPopA = false;
this.hideTabBar();
setTimeout(() => {
this.showPopB = true;
}, 100)
},
写完之后会发现,执行showSharePop
方法达不到预想的效果,弹出Popup B的同时也会让小程序首页底部的tabbar显示如下图:
这是因为执行showSharePop
的时this.showPopA = false
会触发popup A的closeFunPop
方法,查看上面的closeFunPop
方法就会知道在执行该方法的同时会执行uni.showTabBar({ animation: true })
,所有需要调整closeFunPop
方法。并需要在data
中新增一个变量showTarBar: true
。
调整showSharePop
、closeFunPop``makePopShow
方法
// popup A 组件的closeFunPop方法也需要同时调整
closeFunPop(showTarBar=true) {
console.log('close');
if (showTarBar) {
uni.showTabBar({ animation: true });
}
this.showPopA = false;
this.showPopB = false;
},
showSharePop() {
this.showTarBar = false;
this.showPopA = false;
this.hideTabBar();
setTimeout(() => {
this.showPopB = true;
}, 100)
},
// 并且在makePopShow执行始终保持 showTarBar: true
makePopShow() {
this.hideTabBar();
this.showTarBar = true;
setTimeout(() => {
this.showPopA = true;
}, 100)
},
上述的方法是可以成功的解决,Popup B与tabbar同时出现的bug。但是转念意向,如果不引入showTarBar
也能否达到目的呢?那么就成showSharePop
方法入手。
showSharePop() {
// 暂时隐藏这一行
// this.showTarBar = false;
this.showPopA = false;
uni.hideTabBar({
animation: true,
success: () => {
setTimeout(() => {
this.showPopB = true;
}, 100)
}
})
},
调整了showSharePop
方法,调用此方法时会关闭Popup A,并且会触发popup A的closeFunPop
方法(过程会显示tabbar,实际不可见),但是此时popup B没有立马展示而是在tabbar隐藏成功之后才会展示。所有并不会复现