小程序 自定义tabbar + 自定义tabbar样式 + tabbar切换激活样式问题

孟宏才
2023-12-01
  • 我用的是 Vant Weapp  UI组件库,
  • 需要用store 全局共享数据 解决tabbar切换激活样式问题

关于如何使用 Mobx,创建store可参考:微信小程序 Mobx实现数据共享(创建store数据共享 + 页面、组件间的数据传递)_Shimeng_1989的博客-CSDN博客

自定义tabbar 步骤: 

  1. 在app.json中,开启自定义tabbar设置
    // 以下内容可参考 小程序文档 -- 自定义tabbar
    //     1.在package.json 文件中找到/新增 tabBar对象
    //     2.添加custom:true 设置
    //     3.开启自定义tabbar后,在根目录创建 custom-tab-bar 文件夹(名字必须叫这个)。
    //     4.在此文件夹下创建 index.wxml、index.js、index.wxss、index.json 四个文件
    //      (可以将鼠标放在文件夹上,右键 -- (选择)创建component(命名index) -- 回车,则会自从创建这四个文件)  
    
    "tabBar": {
            "custom": true, // 开启自定义tabbar配置
            "list": [{ // list不需要删掉 -- 为了向下兼容老版tabbar
                "pagePath": "pages/index/index",
                "text": "首页",
                "iconPath": "/images/1.png",
                "selectedIconPath": "/images/2.png"
            }, {
                "pagePath": "pages/request/request",
                "text": "请求",
                "iconPath": "/images/1.png",
                "selectedIconPath": "/images/2.png"
            }]
        },
  2. 创建自定义 tabbar 对应文件:( 以下内容可参考 小程序文档 -- 自定义tabbar)
    1. 在package.json 文件中找到/新增 tabBar对象
    2. 添加custom:true 设置
    3. 开启自定义tabbar后,在根目录创建 custom-tab-bar 文件夹(名字必须叫这个)
    4. 在此文件夹下创建 index.wxml、index.js、index.wxss、index.json 四个文件。 (可以将鼠标放在文件夹上,右键 -- (选择)创建component(命名index) -- 回车,则会自从创建这四个文件)  
  3. index.wxml文件:

    <!-- 可根据项目具体情况,参考Vant Weapp官方文档中的配置修改 -->
    <!--  active : 选中 tabbar 的下标 ,info:是否显示消息数量(''/0,则不显示) -->
    <!-- for 循环 tabbar数组 -->
    <van-tabbar active="{{ active_index }}" bind:change="onChange">
      <van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info||''}}">
        <image
          slot="icon"
          src="/images/1.png"
          mode="aspectFit"
          style="width: 30px; height: 18px;"
        />
        <image
        slot="icon-active"
        src="/images/2.png"
          mode="aspectFit"
          style="width: 30px; height: 18px;"
        />
        {{item.text}}
      </van-tabbar-item>
    </van-tabbar>
  4. index.js文件:

    // .js文件
    /* 注意:!!!
            每次切换页面时,更新到跳转页面后会刷新active值(我猜的)。
            所以每次跳转完成后,都会回到 首页(active_index: 0) 的激活状态。
            因此,要将 active_index (选中tabbar下标)放到store全局数据中。
            每次跳转时,更新active_index值,激活状态则可保留在当前跳转页的tabbar上。
    */
    import { storeBindingsBehavior } from "mobx-miniprogram-bindings"
    import { store } from '../store/store'
    Component({
        options: {
            styleIsolation: 'shared', //设置为shared,修改 Vant Weapp UI组件库中的样式才能生效
        },
        behaviors: [storeBindingsBehavior], // 通过 storeBindingsBehavior 来实现自动绑定
        storeBindings: {
            store, // 指定要绑定的 store
            fields: { // 指定要绑定的字段数据
                active_index:'tabbar_active_index',// 获取 store 中,tabbar选中的下标
                num1:'store.store_count1', // 获取list中 首页的 info(消息条数)
                count_sum: 'store_count_sum' // 获取list中 请求的 info(消息条数)
            },
            actions: { // 指定要绑定的方法
                update_tabbarIndex: 'update_Tabbar_active_index' // 更新 tabbar选中的下标
            }
        },
        //  监听 store中值的修改,更新list中的info消息数量
        observers: {
            'num1,count_sum': function (num, sum) {
                // 更新list中的info数量
                this.setData({
                    'list[0].info': num,
                    'list[1].info': sum,
                })
            }
        },
        data: {
            // active_index: 0, // 每次切换页面时,更新为更新跳转页面后会刷新active值(我猜的),所以每次都会回到首页(下标0)的激活状态。所以要将此字段放到store全局数据中,每次跳转时修改当前值,则可保留在跳转页tabbar激活状态上。
            list: [{
                "pagePath": "pages/index/index",
                "text": "首页",
                info: 0,
                "iconPath": "/images/1.png",
                "selectedIconPath": "/images/2.png"
            }, {
                "pagePath": "pages/myfood/myfood",
                "text": "myfood",
                "iconPath": "/images/1.png",
                "selectedIconPath": "/images/2.png"
            }]
        },
        /**
         * 组件的方法列表
         */
        methods: {
            onChange(event) {
                // event.detail 的值为当前选中项的索引
                // this.setData({ active_index: event.detail});// 不在此文件data中声明了,所以不需要setData更新值了。改为触发 store 的 action 中的方法修改store中的 active_index (tabbar_active_index) 了
                this.update_tabbarIndex(event.detail)//更新 store 中 tabbar_active_index(active_index)的值
                // 跳转到对应tabbar的页面
                wx.switchTab({
                    url: `/${this.data.list[event.detail].pagePath}`,
                })
            },
        }
    })
  5. store.js文件:(公共数据文件)

    // store.js文件
    /* 创建store实例对象:
     * observable 中添加字段、计算属性、方法等
     * 计算属性:用get定义,( 且只读,不能修改 )
     * action方法:修改store中的值
     */
    import {
        observable,
        action
    } from 'mobx-miniprogram'
    
    export const store = observable({
        // 字段/数据
        store_count1: 1,
        store_count2: 2,
        tabbar_active_index: 0, // tabbar选中的下标
        // 计算属性:用get定义,(只读不能修改)
        get store_count_sum() {
            return this.store_count1 + this.store_count2
        },
    
        // action方法:用来修改store中的值
        update_storecount1: action(function (step) {
            this.store_count1 += step
        }),
        // 更新tabbar选中下标
        update_Tabbar_active_index: action(function (activeIndex) {
            this.tabbar_active_index = activeIndex
        })
    })

 类似资料: