基于Taro实现小程序custom-tab-bar

基于Taro实现小程序custom-tab-bar

DansRoh Lv4

环境:

  • taro -v 3.6.6
  • react -v 18.0.0

配置app.config.js

找到根目录下的app.config.js配置tarbar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tabBar: {
custom: true,
color: '#000000',
selectedColor: '#DC143C',
backgroundColor: '#ffffff',
list: [
{
pagePath: "pages/home/index",
text: "home",
}
{
pagePath: "pages/mine/index",
text: "mine",
}
]
}

页面配置

在使用tab-bar的页面添加 usingComponents: {}

创建custom-tab-bar组件

warn: 必须在src下,目录名必须为custom-tab-bar

  • 新建 custom-tab-bar/index.jsx文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { useState, useEffect } from "react";
import { switchTab, getCurrentPages } from "@tarojs/taro";
import { CoverView, CoverImage } from "@tarojs/components";

import tabbar_home_on from "../images/tabbar_home_on.png";
import tabbar_home from "../images/tabbar_home.png";
import tabbar_mine_on from "../images/tabbar_mine_on.png";
import tabbar_mine from "../images/tabbar_mine.png";

import "./index.scss";

const tabbarConfig = {
color: "#000000",
selectedColor: "#DC143C",
list: [
{
pagePath: "/pages/home/index",
selectedIconPath: tabbar_home_on,
iconPath: tabbar_home,
text: "",
},
{
pagePath: "/pages/mine/index",
selectedIconPath: tabbar_mine_on,
iconPath: tabbar_mine,
text: "",
},
],
};

function CustomTabBar() {
const { list, color, selectedColor } = tabbarConfig;
const pages = getCurrentPages();
const currentPage = pages[0];
const [selected, setselected] = useState(0);

useEffect(() => {
const index = list.findIndex(
(item) => item.pagePath === "/" + currentPage.route
);
if (index > -1) {
setselected(index);
}
}, [currentPage.route]);

const handleSwitchTab = (url) => {
switchTab({ url });
};

return (
<CoverView className='tab-bar'>
<CoverView className='tab-bar-border'></CoverView>
{list.map((item, index) => {
return (
<CoverView
key={index}
className='tab-bar-item'
onClick={() => handleSwitchTab(item.pagePath)}
>
<CoverImage
src={selected === index ? item.selectedIconPath : item.iconPath}
/>
<CoverView
style={{ color: selected === index ? selectedColor : color }}
>
{item.text}
</CoverView>
</CoverView>
);
})}
</CoverView>
);
}

export default CustomTabBar;
  • 新建 custom-tab-bar/index.scss文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
.tab-bar {
position: fixed;
bottom: env(safe-area-inset-bottom);
left: 50%;
width: 80%;
transform: translateX(-50%);
height: 100px;
border-radius: 50px;
background: rgba(255, 192, 203, .7);
display: flex;
}

.tab-bar-border {
background-color: rgba(0, 0, 0, 0.33);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1px;
transform: scaleY(0.5);
}

.tab-bar-item {
flex: 1;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}

.tab-bar-item cover-image {
width: 54px;
height: 54px;
}

.tab-bar-item cover-view {
font-size: 20px;
}
  • 新建 custom-tab-bar/index.config.js文件
1
2
3
export default {
"component": true
}

遇到的坑

  • 切换tab时,custom-tab-bar组件重加载问题

问题描述:
在点击切换tab时,我们期望custom-tab-bar组件不进行重新渲染,因为重新渲染会导致selected值错误的进行初始化,从而导致页面渲染异常
解决办法:

  1. 使用reducer等在外部储存selected状态,避免selected值丢失,但由于这种方法引入的一个包,增加了项目体积,所以我选择下面的方式
  2. 通过监听路由的变化来改变selected值,如下
1
2
3
4
5
6
7
8
 useEffect(() => {
const index = list.findIndex(
(item) => item.pagePath === "/" + currentPage.route
);
if (index > -1) {
setselected(index);
}
}, [currentPage.route]);
  • 标题: 基于Taro实现小程序custom-tab-bar
  • 作者: DansRoh
  • 创建于 : 2023-06-30 00:00:00
  • 更新于 : 2023-12-22 09:50:00
  • 链接: https://blog.shinri.me/2023/06/30/04_Taro实现小程序自定义custom-tab-bar/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
此页目录
基于Taro实现小程序custom-tab-bar