uniapp 微信小程序 自定义tabBar 导航


Posted in Javascript onApril 22, 2022

需求

分包中如果有6个页面A B C D E F,这6个页面可以作为tabbar页面进行展示,具体配置通过后台接口返回(页面数量限制依然存在 2 - 5),比如后台配置A B C D E这个5个页面为tabbar页面,那么A B C D E将作为tab页展示,跳转方式也是tab方式跳转,跳转到F页面为普通navigate跳转。
这将解决 多商家底部tab配置问题,可以让商家自己配置小程序tab页的展示模式。

实现原理

1.自定义底部导航,数据通过接口获取

2.将需要配置成tab的页面内容抽离成为组件,对应页面直接引用组件,tab页面引用全部组件,并根据当前tab页对应的组件页面路径分别展示。

3.解决组件的生命周期问题。

实现

页面整体结构

uniapp 微信小程序 自定义tabBar 导航

pages.json页面配置好5个tabbar模板页面,并且使用了easycom模式,自动加载组件

"easycom": {
    "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue",
    "^sww-(.*)": "@/components/sww-$1/sww-$1.vue"
  },
"tabBar": {
    "color": "#7A7E83",
    "selectedColor": "#3cc51f",
    "borderStyle": "black",
    "backgroundColor": "#ffffff",
    "list": [
      {
        "pagePath": "pages/index/index"
      },
      {
        "pagePath": "pages/module-page-one/index"
      },
      {
        "pagePath": "pages/module-page-two/index"
      },
      {
        "pagePath": "pages/module-page-three/index"
      },
      {
        "pagePath": "pages/module-page-four/index"
      }
    ]
  }

自定义tabbar使用的uview组件

//sww-tab-bar
<template>
  <u-tabbar v-model="current" :list="vuex_tab_bar.list" :active-color="vuex_tab_bar.activeColor"
            :inactive-color="vuex_tab_bar.inactiveColor"
            @change="onChange"></u-tabbar>
</template>
<script>
import {mapState} from 'vuex'
import {uniLinkTo} from "../../utils/uniPromise";

export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['vuex_tab_bar', 'vuex_tab_page']),
    current: {
      get(){
        return this.$store.state.vuex_tab_bar.current
      },
      set(value){
        this.$store.commit('$uStore',{name: 'vuex_tab_bar.current', value})
      }
    }
  },
  methods: {
    onChange(index) {
      uniLinkTo(this.vuex_tab_page[index], 'tab')
    }
  }
}
</script>
<style lang="scss" scoped>
	::v-deep .u-fixed-placeholder {
		opacity: 0;
	}
</style>

vuex中保存的tabbar数据格式

vuex_tab_bar: {
            list: [],
            activeColor: '',
            inactiveColor: '',
            current: 0
        },
vuex_tab_bar_default: { //接口未获取到数据时使用的默认tabbar
            list: [
                {
                    iconPath: '/static/tab/home.png',
                    selectedIconPath: '/static/tab/home_fill.png',
                    text: '首页',
                    url: '/package/index/index'
                },
                {
                    iconPath: '/static/tab/cat.png',
                    selectedIconPath: '/static/tab/cat_fill.png',
                    text: '分类',
                    url: '/package/product/category/index'
                },
                {
                    iconPath: '/static/tab/community.png',
                    selectedIconPath: '/static/tab/community_fill.png',
                    text: '链圈',
                    url: '/package/index/circle/index'
                },
                {
                    iconPath: '/static/tab/cart.png',
                    selectedIconPath: '/static/tab/cart_fill.png',
                    text: '购物车',
                    // url: '/package/user/order/index'
                    url: '/package/user/cart/index'
                },
                {
                    iconPath: '/static/tab/user.png',
                    selectedIconPath: '/static/tab/user_fill.png',
                    text: '我的',
                    url: '/package/user/index'
                }
            ],
            activeColor: '#e93324',
            inactiveColor: '#666666',
            current: 0
        },

上面的步骤已经完成了自定义底部tabbar,接下来是tab页面中使用组件的方式和tabbar数据的获取

//这里的代码是5个模板tab页面的内容,页面引入了所有可配置成为tab的组件,js部分抽离到mixins中进行代码复用
<template>
  <view class="index-box">
    <block v-if="pageModuleName('/package/index/index')">
      <sww-page-home ref="modulePageRef"></sww-page-home>
    </block>
    <block v-if="pageModuleName('/package/product/category/index')">
      <sww-page-category ref="modulePageRef"></sww-page-category>
    </block>
    <block v-if="pageModuleName('/package/index/circle/index')">
      <sww-page-circle ref="modulePageRef"></sww-page-circle>
    </block>
    <block v-if="pageModuleName('/package/user/cart/index')">
      <sww-page-cart ref="modulePageRef"></sww-page-cart>
    </block>
    <block v-if="pageModuleName('/package/user/index')">
      <sww-page-user ref="modulePageRef"></sww-page-user>
    </block>
    <block v-if="pageModuleName('/package/user/order/index')">
      <sww-page-order ref="modulePageRef"></sww-page-order>
    </block>
    <sww-tab-bar ref="tabBarRef"></sww-tab-bar>
    <sww-login></sww-login>
  </view>
</template>
<script>
import {tabPage} from "../../mixins/tabPage";

export default {
  mixins: [tabPage],
  data() {
    return {
      tabIndex: 4
    }
  }
}
</script>
<style>
page {
  width: 100%;
  height: 100%;
}
.index-box {
  width: 100%;
  height: 100%;
}
</style>
// tabPagemixins
import {mapState} from 'vuex'
const App = getApp()

export const tabPage = {
    computed: {
        ...mapState(['vuex_tab_bar', 'vuex_module_page']),
        //获取当前tab页要显示的页面组件
        pageModuleName(name) {
            return (name) => {
                if (this.vuex_tab_bar.list.length > 0) {
                	//这里的url是后台用户配置的页面路径,此路径是分包中实际存在的页面路径,比如A页面要配置成为tab,那么就将A页面内容抽离成组件,后台配置此页面为tab,只需将A页面的实际路径进行配置即可
                    return this.vuex_tab_bar.list[this.tabIndex].url === name
                } else {
                    return false
                }
            }
        }
    },
    onLoad: function () {
        this.$nextTick(() => {
            try {
                if (this.vuex_tab_bar.list.length === 0) {
                   App.loadTabBarList().then(() => {
                       this.$refs.modulePageRef.$onLoad()
                   })
                } else {
                    this.$refs.modulePageRef.$onLoad()
                }
            } catch (e) {

            }
        })
    },
    // isoH5在onshow时要重置分享
    onShow: function () {
        this.$nextTick(() => {
            try {
                this.$refs.modulePageRef.$onShow()
            } catch (e) {

            }
        })
    },
    onHide: function () {
        this.$nextTick(() => {
            try {
                this.$refs.modulePageRef.$onHide()
            } catch (e) {

            }
        })
    },
    onPullDownRefresh: function () {
        try {
            this.$refs.modulePageRef.$onPullDownRefresh()
        } catch (e) {

        }
    },
    onReachBottom: function () {
        try {
            this.$refs.modulePageRef.$onReachBottom()
        } catch (e) {

        }
    },
    // 微信小程序分享(好友)
    onShareAppMessage: function () {
        return this.$refs.modulePageRef.getShareAppMessage()
    },
    // 微信小程序分享(朋友圈)
    onShareTimeline: function () {
        return this.$refs.modulePageRef.getShareTimeline()
    }
}

总结

到此这篇关于uniapp微信小程序底部动态tabBar的文章就介绍到这了!


Tags in this post...

Javascript 相关文章推荐
一个小例子解释如何来阻止Jquery事件冒泡
Jul 17 Javascript
JQuery调用绑定click事件的3种写法
Mar 28 Javascript
js实现一个链接打开两个链接地址的方法
May 12 Javascript
JavaScript中数据结构与算法(三):链表
Jun 19 Javascript
IE10中flexigrid无法显示数据的解决方法
Jul 26 Javascript
ionic中列表项增加和删除的实现方法
Jan 22 Javascript
JS+DIV实现的卷帘效果示例
Mar 22 Javascript
浅谈Node.js 子进程与应用场景
Jan 24 Javascript
详解JavaScript函数callee、call、apply的区别
Mar 08 Javascript
vue限制输入框只能输入8位整数和2位小数的代码
Nov 06 Javascript
Egg Vue SSR 服务端渲染数据请求与asyncData
Nov 24 Javascript
js实现简单的贪吃蛇游戏
Apr 23 Javascript
vue修饰符.capture和.self的区别
Apr 22 #Vue.js
vue 自定义组件添加原生事件
Apr 21 #Vue.js
vue 自定义的组件绑定点击事件
Apr 21 #Vue.js
微信小程序 WeUI扩展组件库的入门教程
vue组件vue-esign实现电子签名
Apr 21 #Vue.js
微信小程序 根据不同用户切换不同TabBar
Apr 21 #Javascript
vue动态绑定style样式
Apr 20 #Vue.js
You might like
PHP完整的日历类(CLASS)
2006/11/27 PHP
windows下PHP APACHE MYSQ完整配置
2007/01/02 PHP
php 全文搜索和替换的实现代码
2008/07/29 PHP
Apache 配置详解(最好的APACHE配置教程)
2010/07/04 PHP
Windows 下的 PHP-PEAR 安装方法
2010/11/20 PHP
PHP中文件读、写、删的操作(PHP中对文件和目录操作)
2012/03/06 PHP
PHP文件注释标记及规范小结
2012/04/01 PHP
PHP的运行机制与原理(底层)
2015/11/16 PHP
PHP多维数组排序array详解
2017/11/21 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
jQuery第三课 修改元素属性及内容的代码
2010/03/14 Javascript
javascript+iframe 实现无刷新载入整页的代码
2010/03/17 Javascript
js模拟点击事件实现代码
2012/11/06 Javascript
使用JS或jQuery模拟鼠标点击a标签事件代码
2014/03/10 Javascript
js判断当前浏览器类型,判断IE浏览器方法
2014/06/02 Javascript
推荐5 个常用的JavaScript调试技巧
2015/01/08 Javascript
jQuery前端开发35个小技巧
2016/05/24 Javascript
JS查找字符串中出现次数最多的字符
2016/09/05 Javascript
JS基于for语句编写的九九乘法表示例
2018/01/04 Javascript
在vue中更换字体,本地存储字体非引用在线字体库的方法
2018/09/28 Javascript
帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
2019/08/23 Javascript
Nodejs文件上传、监听上传进度的代码
2020/03/27 NodeJs
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
python多线程扫描端口示例
2014/01/16 Python
python提取页面内url列表的方法
2015/05/25 Python
对Python中的@classmethod用法详解
2018/04/21 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
2019/04/11 Python
python使用pymongo操作mongo的完整步骤
2019/04/13 Python
Python 模拟动态产生字母验证码图片功能
2019/12/24 Python
巧用 CSS3的webkit-box-reflect 倒影实现各类动效
2021/03/05 HTML / CSS
西班牙鞋子和箱包在线销售网站:zapatos.es
2020/02/17 全球购物
高中生毕业学习总结的自我评价
2013/11/14 职场文书
责任担保书范文
2014/05/21 职场文书
代理人委托书
2014/08/01 职场文书
创业项目(超低成本创业项目)
2019/08/16 职场文书
nginx.conf配置文件结构小结
2022/04/08 Servers