uniapp实现动态菜单兼容h5、微信小程序和App

1,015 阅读3分钟

uniapp实现动态菜单需求及常见解决方案

最近做的一个uniapp小程序项目,有个需求是将用户端小程序和商家端小程序合并在一起,即根据用户登录角色进入不同界面,这也是常见的动态菜单需求来源。

官网有给出两种方案:1.使用H5端自定义tabbar,全靠内部来实现路由。2.自定义tabbar覆盖原生的。3.微信小程序自定义tabbar官网不推荐。第一种就相当于全局一个tab窗口,tab可以放最外层,切换时不会出现闪烁问题,但是可能因为存在性能问题,切换页面会卡顿。第二种在多页面时,tabbar无法一直保证在底部,因此可能会出现闪烁问题,单页时存在于第一种情况下同样的问题。第三种使用小程序原生的,就没法兼容APP端的,外加体验不佳,官方不推荐。

同时第2、3种都需要在pages里tabbar中列出所有菜单页面,并且微信小程序里限制了最大数不超过5个。虽说uniapp提供了uni.setTabbarItem动态改变菜单,亲测只能改变文字和图标,对pagePathvisible属性无效(后面一查小程序文档原来是小程序没有实现这两个接口)。考虑到实际情况中,客户端+商家端菜单数一般都会超过5个,上述几种方案都无法满足需求。原生Tabbar无法满足动态菜单要求,组件Tabbar又存在性能体验问题,那么有没有一种办法能兼顾两者的优点来达到某种需求和体验的平衡呢?答案是有的

原生Tabbar+组件Tabbar组合方式

假如客户端有['菜单1', '菜单2', '菜单3', '菜单4']这四个菜单,商家端有['商家1', '商家2', '商家3']这3个页面,我们只需要将所有商家页面当做一个菜单和客户端菜单配置到pages.json中,其中将商家菜单设置为false,即不显示

tabbar: [
    { text:'菜单1' }, { text: '菜单2' }, { text: '菜单3' }, { text: '菜单4' },
    { text: '商家', visible: fasle }
]

然后再商家主页面进入的时候隐藏原生Tabbar,利用组件Tabbar去覆盖掉即可:

// Merchant.vue
<template>
<!-- 商家管理页面-->
    <view>
        <view v-show=" current== 'home'">商家一页面</view>
        <view v-show=" current== 'menu1'">商家二页面</view>
        <view v-show=" current== 'menu2'">商家三页面</view>
        
        <!-- 自定义组件tabbar -->
        <my-tabbar :menus="menus" :selectedTab.sync="current"></my-tabbar>
    </view>
</template>

<script>
export default {
onShow() {
    uni.hideTabBar()
},
data() {
    // 因为小程序不支持父组件传递函数,所以只能用事件通信
    return {
            current: 'home',
            menus: [
                    {title: '商家一', id: 'home', icon: 'home.png'},
                    {title: '商家二', id: 'menu1', icon: 'menu1.png'},
                    {title: '商家三', id: 'menu2', icon: 'menu2.png'},
            ]
    }
}
}
</script>

最后,根据用户登录类型,如果是用户端,则不用管,如果是商户端,则先用uni.switchTab切换到商家端主页面,这样用户端是原生Tabbar,商家端是组件Tabbr,其它非Tabbar页面仍然是多页面形式,兼顾需求和体验,亲测兼容H5、小程序、APP,你学废了吗?

不过我还是寄希望于小程序有一天能实现动态更改原生Tabbar菜单(包括能更改pagePathvisible等属性),这样就不用瞎折腾了。