前端开发Taro小程序基于Taro实现小程序custom-tab-bar
Dans Roh
环境:
- 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值错误的进行初始化,从而导致页面渲染异常
解决办法:
- 使用reducer等在外部储存selected状态,避免selected值丢失,但由于这种方法引入的一个包,增加了项目体积,所以我选择下面的方式
- 通过监听路由的变化来改变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]);
|