微信小程序踩坑记录(一)自定义tabbar

背景

项目需求需要使用微信自定义tabbar,中间过程遇到不少坑,再次总结

微信自定义tabbar

1.在app.json中tarBar加入"custom": true
{
  "tabBar": {
    "custom": true,
    "color": "#000000",
    "selectedColor": "#000000",
    "backgroundColor": "#000000",
    "list": [{
      "pagePath": "page/component/index",
      "text": "组件"
    }, {
      "pagePath": "page/API/index",
      "text": "接口"
    }]
  },
  "usingComponents": {}
}

这里需要注意的是,list结构需要保留,因为tabbar的list必须要有值否则会报错。

2.添加 tabBar 代码文件

在代码根目录下添加入口文件:

custom-tab-bar/index.js
custom-tab-bar/index.json
custom-tab-bar/index.wxml
custom-tab-bar/index.wxss

接下来参照微信小程序文档下载demo,自行学习即可,需要注意两点

  1. 这里list里面的pagePath前面是有个’/’,如果发现点击按钮路由没发生变化可能是这个问题
 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: "接口"
    }]
  },

2.tabbar切换的时候显示不正常
因为是自定义tabbar,跳转至其他路由是需要特殊处理,在页面组件show生命周期加如下代码,前后逻辑参考微信官网demo

show() {
  if (typeof this.getTabBar === 'function' &&
     this.getTabBar()) {
     this.getTabBar().setData({
       selected: 0
     })
   }
 }

什么?问题还没解决,请看下面

看到这里,你可能遇到跟我一样的问题,官网的案例有个问题,那就是并不能监听切换tabbar时的操作,也就是说如果就需求需要在跳转的时候做一些”骚操作“,那么你可能需要重写tabbar。

如何操作?

还是在刚刚custom-tab-bar这个组件中,我推荐使用vant一个轻量级的小程序ui库,bug较少,组件比较全。里面的tabbar可以作为ui组件引入,再封装跳转逻辑,一个全新的tabbar就生成了,废话不多说,上代码。

custom-tab-bar/index.wxml

<van-tabbar active="{{ active }}" bind:change="onChange">
  <block wx:key="*this" wx:for="{{tabbarList}}">
    <van-tabbar-item name="{{item.id+'-'+item.pagePath}}">
      <image
        slot="icon"
        src="{{ item.iconPath }}"
        mode="aspectFit"
        style="width: 54rpx; height: 54rpx;"
      />
      <image
        slot="icon-active"
        src="{{ item.selectedIconPath }}"
        mode="aspectFit"
        style="width: 54rpx; height: 54rpx;"
      />
      {{item.text}}
    van-tabbar-item>
  block>
van-tabbar>

custom-tab-bar/index.js

// custom-tab-bar/index.js
import config from '../config/index';
Component({
  
  /**
   * 组件的属性列表
   */
  properties: {
    
  },

  /**
   * 组件的初始数据
   */
  data: {
    active: 1,
    selected: 0
  },

  /**
   * 组件的方法列表
   */
  methods: {
    onChange(e) {
      const [id, url] = e.detail.split('-');
      // 设置全局页面变量id
      wx.pageId = id;
      this.setData({
        active: e.detail
      }, () => {
        wx.switchTab({
          url,
        });
      });
    }
  },
  attached() {
    const tabbarList = [
      {
        id: 1001,
        pagePath: "/pages/index/index",
        text: "首页",
        iconPath: config.imgurl+"/home.png",
        selectedIconPath: config.imgurl +"/home_selected.png"
      },
      {
        id: 1002,
        pagePath: "/pages/my/index",
        text: "我的",
        iconPath: config.imgurl +"/my.png",
        selectedIconPath: config.imgurl +"/my_selected.png"
      }
    ];
    this.setData({
      tabbarList,
      active: `${tabbarList[0].id}-${tabbarList[0].pagePath}`
    });
  },
  observers: {
    //观察者:属性监听
    selected: function (selected) {
      // 设置tabbar选中元素
      const { tabbarList } = this.data;
      const { id, pagePath } = tabbarList[selected];
      this.setData({
        active: `${id}-${pagePath}`
      });
    }
  }
})

需要注意的是这里跳转使用wx.switchTab,进行的路由切换,但是wx.switchTab有个弊端,就是url后不能携带参数,官文没给解决方案,这里使用曲线救国办法,在切换路由前声明全局变量,在wx.上绑定,在另一个页面获取。

另外一点,之前为了在其他页面高亮显示图标在show声明周期写有处理逻辑,现在重写tabbar后,需要在custom-tab-bar/index.js监听其属性并且手动更改ui组件当前选项,切记!

你可能感兴趣的:(微信小程序踩坑记录(一)自定义tabbar)