• 微信小程序开发tabbar组件页面转跳图标没有正确显示的原因
  • 发布于 2个月前
  • 329 热度
    0 评论
  • Scys
  • 5 粉丝 39 篇博客
  •   
先说明一下问题出现的环境,使用的是原生小程序开发,然后开启了自定义tabBar组件配置,配合了vant-tabbar组件实现底部tabbar功能,但是发生了一个很有趣的现象,页面能够正确的跳转,但是图标却不能正确高亮显示,我们先来看一下bug的演示。

产生这个问题的原因
虽然老师说是因为微信小程序中的swichTab方法会改变active的值,所以放在全局状态管理中就能够解决这个问题,因为全局状态管理想修改数据就只能通过调用mutations中的方法进行修改,但那种浅显的解释很快就被我打破,如果说是因为这个问题那么我改个变量名不就好了,何必将数据放到全局状态管理?

事实是改了变量名还是有这个bug,所以老师的那个解释并不成立,至于为什么全局状态管理能够解决这个问题的原因我会在后续指出,这就让我更迷惑了,秉着不想稀里糊涂的过掉这个知识点,我开始了铺天盖地的百度,老实说百度上并没有人真正的回答了这个bug产生的原因,但是我在csdn上找到了一个非常有价值的线索:

注意:如果在 A 页面和 B 页面都渲染了一个 Tabbar 组件,那么这两个 Tabbar 的状态是不共享的。
对,就是这个,所以我立刻在组件上添加了一个生命周期created,发现重新编译后分别点击其他页面就创建了三次tabbar组件,说明这个tabbar创建了三个,配合那个线索得出一个假设,这些tabbar相互独立,并且因为每次创建时active设置的值为0,所以我们会发现前两次跳转时tabbar的图标高亮都会跳回第一个图标,直到第三次跳转异常开始,那么我们来好好解读一下这些“异常”是为什么?

先来看看van-tabbar的跳转代码是什么,配合代码可能更能明白下面的思路。
onChange(event) {
    wx.switchTab({
        url: '/' + this.data.list[event.detail].pagePath,
    })
    this.setData({
        active: event.detail
    })
}
我们从第一次开始解释,当进入页面时高亮图标是第一个,我们点击第二个页面时,因为是第一次进入新的页面,也就等于创建了一个新的tabbar,所以第二个页面中的tabbar组件里的active是0,然鹅,第一个页面中的tabbar函数并没结束,这时候就能发现我们跳转的是第二个页面,但active修改的其实是第一个页面tabbar组件中active,这时函数才结束,所以得出结论第一个页面存放的值为1。

从第二个页面跳转到第三个页面时,又因为是第一次进入新页面,所以等于创建了一个新的tabbar,这时第三个页面的active存放的是0,然鹅,第二个页面中的tabbar函数也还没结束,这时候发现虽然说跳转的是第三个页面,但active修改的其实是第二个页面中的tabbar组件中的active,这时函数结束,得出结论,第二个页面存放的值改成了2。

接下来我点击的是第二个页面,也就是说从第三个页面跳到第二个页面,根据前一段解释知道这时候第二个页面的tabbar组件里的active其实是2,所以高亮的图标是第三个页面的图标,然鹅第三个页面的函数并没有结束,所以虽然跳转的是第二个页面,但实际修改的是第三个页面的active,这时函数结束,得出结论,第三个页面存放的值改成了1。

好,到这里其实我们就可以发现了,第一个页面存放的是1,所以当我再次跳转回第一个页面时高亮的图标是第二个页面的图标,然后我们发现第三个页面的值存放的也是1,所以当我再次跳转回第三个页面时,这时候高亮的还是第二个页面的图标没有变。

以上就是我推导出来的图标高亮“异常”的过程了,可能很绕,但是我每个跳转的动作都特地分段去解析了,如果你还是有点懵就多看几遍,然后配合下方的gif理解更快嗷。

解决办法
所以你发现了吗,老师的解释并不一定是正确的,真正的原因其实就是因为小程序给每个新的页面都创建了一次tabbar组件,导致他们的数据并不互通,各干个的,那么老师给出的解决办法为什么又能解决这个bug呢?

原因很简单,由上我们知道是因为他们数据并不互通才导致的这种“乱象”,所以我们只需要让他们使用同一个数据源就能够解决问题了,尽管他们还是三个独立的组件,但是我们可以让他们获取的active这个值存放在全局状态管理中,三个组件都往这个全局状态中读取并修改,这时候他们就能够同步了,而且不会有任何问题。

理解了上面的推导过程之后就知道有很多解决办法了,但是最简单的当然还是使用全局状态管理啦。

最后
其实这个问题困扰了我几天,但是因为不放弃,所以最终在百度中寻找到了一点点启发,本来打算是去好师傅平台约个好师傅的,但是因为时间都冲突,还得上课,就只能自己解决了,做完之后成就感还是挺强的,毕竟这是连老师都解释的稀里糊涂的东西,而且百度也没有一个完整的答案(或许有,我没找到吧)。

最后的最后,希望这篇文章能真的帮助到你,我觉得心存疑问这是一个很好的事情,没有自己的思考光听老师讲也是学不好编程的,虽然我自己编程能力也很烂哈哈嗝~
用户评论