用uni-app开发小程序时无法在非tabBar页面触发setTabBarBadge的原因及其解决方案

407 阅读2分钟
  • 在开发购物类小程序时,有可能会有在tabBar的购物车图标上显示角标,以此来展示用户购物车购买数量的需求,这种情况下就需要使用uni-ap自带的api--uni.setTabBarBadge来显示角标,使用uni.removeTabBarBadge来关闭显示角标,可这个api却有着长久的未修复bug:无法在非tabBar页面使用。如果强行使用则会发生报错,页面也不会更新最新数据。

image.png

  • 为什么会出现这种情况呢?其根本原因就是因为小程序的页面组件一般不会主动卸载,在初次进入页面时,就已经触发了设置角标用的监听器,所以再次进入页面时就不会再次触发监听器了,也就不会更新数据了
    watch: {
    // total为角标显示的数据
    total: {
      immediate: true,
      handler(newVal) {
        if (newVal > 0) {
          uni.setTabBarBadge({
            index: 2,
            text: '' + newVal,
          })
        } else {
          uni.removeTabBarBadge({
            index: 2,
          })
        }
      },
    },
  },

所以为了再次触发监听,从而获取最新数据,只需在后面再写一个进入页面就会触发的onShow钩子函数即可

   onShow() {
    if (this.total > 0) {
      uni.setTabBarBadge({
        index: 2,
        text: '' + this.total
      })
    } else {
      uni.removeTabBarBadge({
        index: 2
      })
    }
  }

这个时候setTabBarBadgeremoveTabBarBadge的触发问题bug已经被完美解决了,但是页面还会报错,那是因为就算onShow可以触发更新最新数据,但是还是会执行监听里面的事件,这时候只需要在监听里面手动添加判断,使得其在非tabBar页面不继续执行后续函数即可

// 完整写法:根据tabBar页面与页面栈匹配,从而限制只在tabBar页面触发
  watch: {
    total: {
      immediate: true,
      handler(newValue) {
        const pagePath = ['pages/home/home', 'pages/cart/cart',
        'pages/category/category', 'pages/my/my']
        const currentPage = getCurrentPages()
        const currentPath = currentPage[currentPage.length - 1].route
        console.log(currentPath)
        if (!pagePath.includes(currentPath)) return
        if (newValue > 0) {
          uni.setTabBarBadge({
            index: 2,
            text: '' + newValue
          })
        } else {
          uni.removeTabBarBadge({
            index: 2
          })
        }
      }
    }
  }