前言
uniApp
自带有中间凸出按钮,midButton
属性用来设置凸出按钮图标及文字。
当使用uniApp
开发微信小程序时,涉及到tabBar
中间凸起的需求,此功能在微信小程序中不支持,别无他法,只能自定义tabBar
。
在实现自定义tabBar
组件之前,需要把路由配置好。
有一点矛盾,但是未能找到合理的解释。
自定义tabBar
时可以不用配置pages.json
文件中的tabBar
选项。
如果配置了需要在APP.vue
以及所用到的tabBar
页面生命周期中调用uni.hideTabBar();
对原始tabBar
进行隐藏,
但是编译为微信小程序时会报错,所以不配置为好,省得麻烦。
虽然是自定义tabBar
,使用的是v-if
方式实现,但是pages.json
文件中的pages
选项依然需要配置,否则出错。
第一步
{ "pages": [ { "path": "pages/login/index", "style": { "navigationBarTitleText": "登录" } }, { "path": "pages/tabBar/index", "style": { "navigationBarTitleText": "tabBar页面" } }, { "path": "pages/tabBar/aA/index", "style": { "navigationBarTitleText": "aA页面" } }, { "path": "pages/tabBar/bB/index", "style": { "navigationBarTitleText": "bB页面" } } ] }
配置
pages.json
文件中的pages
属性。
第二步
解析
在
pages
目录下新建一个名为tabBar
的目录,在tabBar
目录中新建名为index
的vue
文件,此页面文件需要配置到路由中,因为不使用components
方式实现tabBar
。
html
<template> <view> <!-- tabBar页面 --> <view> <a-a v-if="STB === '1'" ref="ref1" /> <b-b v-if="STB === '3'" /> </view> <!-- 全局面板 --> <view> <c-c ref="refQCC"></c-c> </view> <!-- tabBar选项卡 --> <view class="w_100_ pf l_0 b_0"> <view class="df jc_se p_t_18 p_b_18 bc_fff f_ds_01 f_s_22"> <view class="df fd_c ai_c cursor_p" @click="tabBar('1')"> <image class="w_38 h_40" :src="'/static/image/tabBar/' + [STB === '1' ? 's_aA' : 'aA'] + '.png'"> </image> <view class="m_t_4" :class="[STB === '1' ? 'color_222' : 'color_a5aabb']">aA页面</view> </view> <view class="w_112 h_112 df jc_c ai_c bc_fff radius_50_ m_t_r50" @click="tabBar('3')"> <image class="w_86 h_86 cursor_p" src="@/static/image/tabBar/add.png"></image> </view> <view class="df fd_c ai_c cursor_p" @click="tabBar('3')"> <image class="w_38 h_40" :src="'/static/image/tabBar/' + [STB === '3' ? 's_bB' : 'bB'] + '.png'"> </image> <view class="m_t_4" :class="[STB === '3' ? 'color_222' : 'color_a5aabb']">bB页面</view> </view> </view> </view> </view> </template>
本例不展示样式,使用公共样式,通过类名基本可以得知样式属性及值。
df
:display: flex;
fd_c
:flex-direction: column;
jc_se
:justify-content: space-evenly;
JavaScript
import aA from './aA/index.vue' import bB from './bB/index.vue' import cC from '@/components/cC/index.vue' export default { name: 'index', components: { aA, bB, cC }, data() { return { STB: '1' } }, created() { let self = this; // 页面加载时执行 // 或 // 非tabBar页面进入时执行 uni.getStorage({ key: 'STB', success: ({ data }) => self.setTabBar(data) }); }, // 滚动条事件 onPageScroll({ scrollTop }) { let STB = this.STB, ref1 = this.$refs.ref1; if (STB === '4' && scrollTop === 0) { ref1.contact('0'); } }, // 触底事件 onReachBottom() { let STB = this.STB, ref1 = this.$refs.ref1; if (STB === '4') { ref1.contact('1'); } }, methods: { // 设置tabBar高亮 setTabBar(str) { let self = this; // 第一步 // 把获取到的值存到本地 uni.setStorage({ key: 'STB', data: str, // 第二步 // 从本地存储中获取值放到页面中 success: () => uni.getStorage({ key: 'STB', success: ({ data }) => self.STB = data }) }); }, // tabBar点击事件 tabBar(str) { // 点击凸起按钮时 if (str === '3') { // 通过ref打开全局面板 this.$refs.refQCC.isShow = true; } else { // 调用tabBar赋值函数 this.setTabBar(str); } } } }
导入三个组件,前两个归类为
pages
页面组件,两个页面组件在pages
目录下的tabBar
目录下创建,与tabBar
目录下的index.vue
文件同级,他们属于目录类型,目录的下一级才是.vue
文件;后一个归类为components
组件。
定义STB
变量来控制tabBar
选项的高亮功能。从功能需要用本地存储记录STB
的值,因为需要判断从子页面进入tabBar
页面的方式。
方式一: 点击返回进入tabBar
页面
方式二: 通过路径进入tabBar
页面
如果通过点击返回进入tabBar
页面,那么在点击的页面直接跳转对应路由即可,意思是从哪来回哪去。
如果通过点击指定路由进入tabBar
页面,那么可以设置进入首页,即tabBar
的第一项。
tabBar
页面触底和触顶的触发。
第三步
// 封装返回tabBar页面 backTabBar(str) { uni.setStorage({ key: 'STB', data: str, success: () => uni.redirectTo({ // 这个路径是包裹着两个tabBar页面的父页面 url: '/pages/tabBar/index' }) }); }, // 返回(从哪来回哪去) back() { let self = this; uni.getStorage({ key: 'STB', success: ({ data }) => self.backTabBar(data) }); }, // 关闭(直接回到tabBar页面的第1项) close() { this.backTabBar('1'); },
从子页面进入
tabBar
页面,也是本例中的cC
组件。