菜鸟读文档-Vant Weapp-3(用自己摸索的方法实现Tabbar标签栏点击跳转)
发布于 4 年前 作者 xiuying02 4453 次浏览 来自 分享

菜鸟读文档-Vant Weapp-3(用自己摸索的方法实现Tabbar标签栏点击跳转)

正文

似乎很好用的样例代码

我们首先将Vant WeappTabbar标签栏文档的__基础用法样例__直接复制到custom-tab-bar文件夹中

  • index.wxml

    <!-- 为了方便演示, 我将样例中的tabbar数量减少到两个 -->
    <van-tabbar>
      <van-tabbar-item icon="home-o">标签1</van-tabbar-item>
      <van-tabbar-item icon="search">标签2</van-tabbar-item>
    </van-tabbar>
    
  • index.js

    Page({
      data: {
        active: 0,
      },
      onChange(event) {
        // event.detail 的值为当前选中项的索引
        this.setData({
          active: event.detail
        });
      },
    });
    

在输入完基础用法样例中的代码后发现: 点击tabbar子项后, 该子项将会进入活跃状态. 我们需要的tabbar点击跳转功能就已经实现一半了(什么嘛,文档样例还是挺好用的嘛)

接下来需要做的就是在tabbar子项进入活跃状态的同时进入到对应的页面

问题多多的页面跳转

既然我们的tabbar只剩下页面跳转功能需要实现了, 我们就直接去微信小程序文档中找到相应的路由API: wx.switchTab, 按照文档中的样例输入到自己项目中的index.js文件中就完事了(然而欲速则不达啊…)

为了代码更可读, 我们将代码稍微修改一下

  • index.js

    Page({
      data: {
        // 将tabbar需要的所有数据全部封装到tabbars对象中
        tabbars: {
          // tabbar所有的子项
          list: [{
            pagePath: "/pages/page1/page1",
            text: "第一页",
            icon: "home-o"
          }, {
            pagePath: "/pages/page2/page2",
            text: "第二页",
            icon: "search"
          }],
          // 当前活跃的tabbar子项
          active: 0,
        },
      },
      onChange: function(event) {
        // event.detail 的值为当前选中项的索引
        console.log(event.detail);
        const index = event.detail;
        // 活跃tabbar子项设置
        this.setData({
          "tabbars.active": index
        });
        // 页面路由
        wx.switchTab({
          url: this.data.tabbars.list[index].pagePath
        });
      },
    });
    
  • index.wxml

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

然而在代码输入完成后, 测试却发现效果并不和预想中的一样…

从gif图中可以看到, 在按下tabbar子项进行跳转后, 上方页面实现了正常的页面跳转, 但下方tabbar栏中的子项却没有进入对应的活跃状态…

分析问题

从出现的问题我们可以看出: 当使用tabbar栏进行页面跳转时, tabbar子项的活跃状态会保持之前的活跃状态, 而不是随页面跳转而相应变化, 即index.js文件中tabbars对象的active属性的值没有进行相应的改变, 我认为是我对自定tabbar栏的原理理解存在问题

在微信小程序文档中的自定义tabBar, 我找到了如下内容

每个 tab 页下的自定义 tabBar 组件实例是不同的,可通过自定义组件下的 getTabBar 接口,获取当前页面的自定义 tabBar 组件实例。

这波啊, 这波是读者不认真读文档急死文档编写者

对于这段话的我的理解是: 每当使用wx.switchTab()切换到一个新的tab页后, 该页面下的自定义tabbar栏都会基于custom-tab-bar文件夹下的文件重新渲染, 又因为在index.js中, tabbars对象的active属性的值默认设置为0, 因此每一次从当前tab页切换到新的tab页时, 底部tabbar栏都会是第一个tabbar子项为激活状态, 如下图所示(为了演示, 我加入了第三个tabbar子项):

上述gif图实际上的路由逻辑是:

  1. 从页面1路由到页面2
  2. 从页面2路由到页面3

可以看到, 每一次路由到新的页面, 底部tabbar栏都会是第一个tabbar子项为激活状态

自己摸索的方法

既然已经找到了问题背后的原因, 接下来要做的就是解决问题

既然每一次路由到新的页面都会重新渲染底部的tabbar栏, 而index.js文件中tabbars对象的active属性设置默认值会导致底部tabbar栏激活状态和目标页面不匹配, 那我认为可以这样处理

  1. 取消tabbars对象的active属性的默认值

    active: null
    
  2. 利用this.getTabBar().setData()接口, 在目标页面为tabbar栏设置对应的活跃状态

    • index.js

        onChange: function(event) {
          // event.detail 的值为当前选中项的索引
          const nextIndex = event.detail;
      
      <span class="hljs-comment">// 删除了active数值设置相关代码</span>
      
      wx.switchTab({
        <span class="hljs-attr">url</span>: <span class="hljs-keyword">this</span>.data.tabbars.list[nextIndex].pagePath
      });
      

      }

    • page1.js(其它需要通过tabbar路由的页面也需要编写相应代码)

        // 在页面的onLoad周期设置对应的活跃tabbar项
        onLoad: function (options) {
          this.getTabBar().setData({
            // CURRENT_ACTIVE_TABBAR: 常量, 当前页面对应的活跃tabbar项
            "tabbars.active": CURRENT_ACTIVE_TABBAR
          });
        },
      

输入上述代码之后, 效果如下图所示:

可以看到路由页面和下方tabbar栏中子项的激活状态是对应的了

预告

从组件的角度处理自定义tabbar

虽然用自己摸索的方法似乎将问题解决了, 但是, 我在微信小程序文档中的自定义tabBar, 又找到了如下内容:

注意:如需实现 tab 选中态,要在当前页面下,通过 getTabBar 接口获取组件实例,并调用 setData 更新选中态。可参考底部的代码示例

微信小程序文档中提供的实现tab选中态代码的核心虽然也是this.getTabBar().setData()接口, 但却不像Vant Weapp文档中那样, 将自定义tabbar栏处理为Page对象, 而是处理为Component对象, 关于个中缘由, 只能下期再聊了

回到顶部