Uniapp开发 微信小程序自定义导航栏

2,674 阅读4分钟

前言

由于微信小程序的官方 tabBar 配置功能有限, 例如微信小程序默认的 tabBar 不美观或者没有办法根据角色权限,动态的显示底部tabBar,那自定义 tabBar 成为了很多开发者实现复杂底部导航的选择。文章讲述了在使用微信小程序自定义tabBar时遇到的问题,如闪烁和图标与页面跳转不一致。

其实要实现 自定义tabBar目前有2种实现方式:

🎈 第一种 :自定义公共组件

那就是在components目录下新建组件页面CustomTabBar,在CustomTabBar.vue中开发自定义组件,然后在需要用到tabBar的页面引入注册并使用组件,通过父子组件通信的方式传参当前是哪个索引页面selected,在子组件通过props接收并使用即刻。

❌❌❌但是这种选择弊端就是在用到的页面进行引入,如果我后期开放10个页面,但是根据不同角色权限显示5个不同的页面,还是需要在10个页面里面进行引入使用。不够完美。

🌈 第二种 :微信官方 提供的 custom-tab-bar

image.png

自定义组件的方式编写即可,该自定义组件完全接管了原生的 tabBar 的渲染。

简单回顾下配置流程 这里还是有好多坑的

1. 创建custom-tab-bar组件

组件名和放置的位置都更官网示例的要一致,要在根目录下!!,并且是custom-tabBar/index的命名方式。

image.png

📍 注意! 这个文件夹下的文件不会被解析为微信小程序支持的格式。如果不是微信小程序原生开发 就把这个文件下的文件给改为微信小程序一样的模版格式

image.png

这里可以偷个懒 直接去微信官方这个地址 developers.weixin.qq.com/miniprogram… 把官方demo那个文件给拷贝一份然后改改,省的麻烦。算了我直接放上去吧 这是官方的关于tabbar的demo 可以参考一下

<!-- custom-tab-bar/index.wxss -->

.tab-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 48px;
  background: white;
  display: flex;
  padding-bottom: env(safe-area-inset-bottom);
}

.tab-bar-border {
  background-color: rgba(0, 0, 0, 0.33);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 1px;
  transform: scaleY(0.5);
}

.tab-bar-item {
  flex: 1;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.tab-bar-item image {
  width: 27px;
  height: 27px;
}

.tab-bar-item view {
  font-size: 10px;
}


<!-- custom-tab-bar/index.js* -->

Component({
  data: {
    selected: 0,
    color: "#7A7E83",
    selectedColor: "#3cc51f",
    list: [{
      pagePath: "/index/index",
      iconPath: "/image/icon_component.png",
      selectedIconPath: "/image/icon_component_HL.png",
      text: "组件"
    }, {
      pagePath: "/index/index2",
      iconPath: "/image/icon_API.png",
      selectedIconPath: "/image/icon_API_HL.png",
      text: "接口"
    }]
  },
  attached() {
  },
  methods: {
    switchTab(e) {
      const data = e.currentTarget.dataset
      const url = data.path
      wx.switchTab({url})
      this.setData({
        selected: data.index
      })
    }
  }
})

其中 iconPath 代表未被选中时的 icon 图标,selectedIconPath 代表当前被选中时的  icon图标

📍 跳转的时候url改成模板字符串的写法,并且前边要加上 /

<!-- custom-tab-bar/index.json -->

{
  "component": true
}
<!--custom-tab-bar/index.wxml-->

<view class="tab-bar">
  <view class="tab-bar-border"></view>
  <view wx:for="{{list}}" wx:key="index" class="tab-bar-item" data-path="{{item.pagePath}}" data-index="{{index}}" bindtap="switchTab">
    <image src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></image>
    <view style="color: {{selected === index ? selectedColor : color}}">{{item.text}}</view>
  </view>
</view>

📍 这里可以用组件来渲染 也不是说非要自己写 html css样式 以防踩坑我这里就是引入了 Vant 的 tabber 组件

到这里创建文件就算可以了。

2. 配置 app.json

修改 app.json 文件,加上这行代码custom:true 将 tabBar修改为自定义tabBar, list 别注释!别删除 保持不变,不要变!!!,留着听别的博主说有坑,我这里没去踩 主打一个听劝就完事了。 image.png

📍 不要忘记你的路由页面要在"pages"数组里面进行注册声明 要不然会报错的。

📍不需要在 app.json 的 usingComponents 引入 tabBar 组件,如果你放置目录与命名正确,小程序会自动引入

官网的demo运行起来就是这样的 image.png

我把官网的demo文件改改后 发现跳转tabbar会出现闪烁问题 如A→B,切换的时候页面会icon会闪烁一下,然后好多开发者都遇到了这个情况~~~

这里说一下原因:

📍当你切换页面的时候相当于重新加载组件了,这时候组件中的值会重置,会导致data值重置就会出现闪烁以及点击项与高亮项不一致。

解决办法

我是这样解决的 不在tap点击函数内修改data的索引,当你切换页面的时候相当于重新加载组件了,修改了又给重置了。试试在页面完成加载后拿到当前路由路径去匹配索引,然后赋值。

image.png

image.png

这样整体功能就算是完成了50%了,剩下的就是根据业务角色权限来动态控制tabbar list的数据结构了。

写在最后


本文仅供参考,如有不足之处,欢迎您指出并提出改进建议。如果您有更好的解决方案,也非常欢迎分享!您的反馈对我的成长至关重要。谢谢阅读,也希望本篇内容对您有所帮助。