1. Taro实现自定义Tabbar
平时在开发时会遇到一些Tabbar中间有悬浮按钮的需求,比如这样
这时候就需要自定义底部Tabbar,按照官方文档,我们可以这样操作
1.修改app.config配置
tabBar: {
selectedColor: themeVars.nutuiColorPrimary,
borderStyle: 'white',
custom: true,
list: [
{
pagePath: 'pages/index/index',
text: '首页',
iconPath: 'assets/images/home.png',
selectedIconPath: 'assets/images/home-s.png',
},
{
pagePath: 'pages/my/my',
text: '我的',
iconPath: 'assets/images/user.png',
selectedIconPath: 'assets/images/user-s.png'
}
]
},
2.在src新建目录和文件
3.然后我们在index.tsx中填入我们的组件内容
import { useEffect, useState } from 'react'
import { View } from '@tarojs/components';
import { Button, Image } from '@nutui/nutui-react-taro';
import './index.scss'
import ThemeProvider from '@/theme-provider/ThemeProvider';
import { themeVars } from '@/theme-provider/theme.config';
import Taro from '@tarojs/taro';
// import { useTabBarStore } from '@/store';
function CustomTabBar() {
const [curentIndex, setCurrentIndex] = useState(0)
// const {selectTab,setSelectTab} = useTabBarStore()
const list = [
{
pagePath: '/pages/index/index',
text: '首页',
iconPath: '/assets/images/home.png',
selectedIconPath: '/assets/images/home-s.png',
},
{
pagePath: '/pages/my/my',
text: '我的',
iconPath: '/assets/images/user.png',
selectedIconPath: '/assets/images/user-s.png'
}
]
return (
<ThemeProvider>
<View className='tab-bar'>
<View style={{ display: 'flex', justifyContent: 'space-around', alignItems: 'center', width: '100%',paddingTop: '5px' }}>
{
list.map((item,index) => (
<View className='tab-bar-item' key={index} onClick={ () => {
setCurrentIndex(index)
Taro.switchTab({ url: item.pagePath }) // 跳转到指定页面
}} >
<Image src={index === curentIndex ? item.selectedIconPath : item.iconPath} />
<View style={{ marginTop: 5, color: index === curentIndex ? themeVars.nutuiColorPrimary : '#999' }}>{item.text}</View>
</View>))
}
<Button className='middle-btn'>1</Button>
</View>
</View>
</ThemeProvider>
)
}
export default CustomTabBar
这里要注意list从原来的app.config复制过来的,需要改些目录,比如pagePath在app.config里开头是不需要/,但是这里需要
这里实现底部Tabbar凹陷形状的思路狠简单粗暴,直接拿背景图进行覆盖,然后按钮定位上去,这里就不细讲。
当完成了基本的Tabbar之后是这样的
然后就遇到了一个问题
2. 底部Tabbar切换页面和高亮不同步
意思就是说,当我点击某个tab时,会立即切换页面,但是并不高亮,只有我再次点击这个tab才会高亮,如图,
这个问题其实是因为我们的切换页面后状态会重新执行,这个地方用全局状态就可以解决,我这里之前用了zustand,所以这里还是只用zustand进行全局状态管理
1.新建useTabBarStore.ts文件,填入如下代码
import { create } from "zustand";
interface IuseTabBarStore {
selectTab: number;
setSelectTab: (selectTab: number) => void;
}
const useTabBarStore = create<IuseTabBarStore>((set) => ({
selectTab: 0,
setSelectTab: (selectTab: number) => set({ selectTab }),
}))
export default useTabBarStore;
2.然后就完美解决了
import { useEffect, useState } from 'react'
import { View , Image} from '@tarojs/components';
import { Button } from '@nutui/nutui-react-taro';
import './index.scss'
import ThemeProvider from '@/theme-provider/ThemeProvider';
import { themeVars } from '@/theme-provider/theme.config';
import Taro from '@tarojs/taro';
import { useTabBarStore } from '@/store';
function CustomTabBar() {
const {selectTab,setSelectTab} = useTabBarStore()
const list = [
{
pagePath: '/pages/index/index',
text: '首页',
iconPath: '/assets/images/home.png',
selectedIconPath: '/assets/images/home-s.png',
},
{
pagePath: '/pages/my/my',
text: '我的',
iconPath: '/assets/images/user.png',
selectedIconPath: '/assets/images/user-s.png'
}
]
return (
<ThemeProvider>
<View className='tab-bar'>
<View style={{ display: 'flex', justifyContent: 'space-around', alignItems: 'center', width: '100%',paddingTop: '5px' }}>
{
list.map((item,index) => (
<View className='tab-bar-item' key={index} onClick={ () => {
setSelectTab(index)
Taro.switchTab({ url: item.pagePath }) // 跳转到指定页面
}} >
<Image src={index === selectTab ? item.selectedIconPath : item.iconPath} style={{ width: 24, height: 24 }}/>
<View style={{ marginTop: 5, color: index === selectTab ? themeVars.nutuiColorPrimary : '#999' }}>{item.text}</View>
</View>))
}
<Button className='middle-btn'>1</Button>
</View>
</View>
</ThemeProvider>
)
}
export default CustomTabBar