微信小程序开发坑点

自定义tab-bar图标切换问题

问题描述

点击tab-bar的图标,发现页面已经切换获取了,但是点击的那个图标亮起来的地方还位于上一个页面的图标,然后我们再次点击我们当前页面的图标,亮起来的图标才切换到当前页面。

问题代码

<van-tabbar active="{{ active }}" bind:change="onChange">
  <block wx:for="{{list}}" wx:key="index">
     <van-tabbar-item icon="{{item.icon}}" >{{item.text}}</van-tabbar-item>
  </block>
</van-tabbar>

本段代码是位于自定义tab-bar图标文件夹"custom-tab-bar"的wxml文件内容

// custom-tab-bar/index.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    active:0,
    list:[
      {
        icon:"home-o",
        text:"首页",
        pagePath:"/pages/index/index"
      },
     {
        icon:"search",
        text:"搜索",
        pagePath:"/pages/search/seach"
      },
      {
        icon:"friends-o",
        text:"好友",
        pagePath:"/pages/friends/friends"
      },  

      {
        icon:"setting-o",
        text:"设置",
        pagePath:"/pages/setting/setting"
      }
    ]
  },
  // 底部 点击切换触发
  onChange(event) {
    const self =this;
    console.log("底部onchange",event);
    this.setData({ active: event.detail });
    wx.switchTab({
      url: self.data.list[event.detail].pagePath,
    })
  },

})

本段代码位于自定义tab*bar图标文件夹"custom-tab-bar"的js文件内容

代码功能

wxml代码通过block内for遍历完成了对tab-bar 图标和文字
的渲染,其图标和文字的数据位于上面js文件的list数组之
中,active是tab-bar自带的一个关键词,其标记当前选中
tab-bar的索引是多少。所以我们在js文件的data中初始化
了一个active,然后通过点击触发函数 onChange(event)
中的this.setData来实现点击对应的tab-bar然后active
更新到tab-bar对应的下标,这里我们用的是
event.detail,这个event.detail我们可以通过  
console.log("底部onchange",event);看到其规律
其实就是data中我们list内各个tab-bar设置的顺序

问题分析

通过我们对代码功能的分析我们发现其实我们这样设置的逻辑上的确没有问题 ,但是在小程序中微信不会自动管理自定义 tabBar 的状态,所以开发者需要手动同步 tabBar 的显示状态与当前页面。而我们恰好用的就是第三方的tab-bar标签栏,换句话来说就是我们在自定义tab-bar图标文件夹内active的确更新了,但是我们tab--bar具体页面的active却没有更新,导致了数据更新的滞后。

问题解决

既然问题出在微信不会自动管理tab-bar的状态,那我们就手动进入每个切换到的页面的js文件中进行一个状态的管理即可,而当我们通过 tabBar 切换到一个新页面时,微信小程序框架会执行新页面的 onShow 函数。在自定义 tabBar 的情况下,我们就可以利用这个时机,手动设置 tabBaractive 状态,具体的代码如下:

onShow() {
    if(typeof this.getTabBar === "function" &&        this.getTabBar()){
      this.getTabBar().setData({
        active:3 
        })
    }
  },

这里的active: 3 代表了当前我们处于第四个tab-bar,我们要对每个tab-bar的页面的onshow()写入以上代码,但是其中的active后面的值要根据页面的先后顺序来具体情况具体分析

解决原理

这个 if 语句首先检查 this.getTabBar 是否为一个函数,这是为了确保 getTabBar 方法存在并可以被调用。这个方法是小程序官方提供的,用于获取自定义 tabBar 的实例。第二个条件 this.getTabBar() 判断调用 getTabBar 后,是否真的得到了一个 tabBar 实例,如果得到的是 nullundefined,就不会执行后面的代码。也就是说当我们确定我们当前页面的确有一个tabBar示例的时候我们给active进行更新,这样完全保证了我们tab-bar 状态更新的同步