背景
- 使用
antd UI框架的Tabs组件,需要根据设计图对原生样式再次修改,步骤繁琐。 Tabs标签内,需要再配置TabPane标签和每页内容,至少十几行才能完成。
// 使用antd
<Tabs defaultActiveKey="1" onChange={callback}>
<TabPane tab="城市概况" key="1">
<Outline />
</TabPane>
<TabPane tab="城市历史" key="2">
<History />
</TabPane>
<TabPane tab="地理位置" key="3">
<Geo />
</TabPane>
</Tabs>
本文使用react hook,将tab所有相关的操作都进行封装,只留下一个tabSet配置接口。
仅仅使用一行代码即可在页面显示Tab组件。
使用如下
<Tab tabSet={tabSet} />
tabSet的格式如下
const tabSet = {
'城市概况': <Outline />,
'城市历史': <History />,
'地理位置': <Geo />,
}
其中,tabSet的属性名是tab的标签名;
值是tab每个标签页要显示的内容,以组件形式引入。
Tab组件的实现
完整代码
function Tab(props) {
const { tabSet } = props
const arr = Object.keys(tabSet) // 由tab标签名组成的数组
const [selected, setSelected] = useState(arr[0]) // 当前选中的tab标签
function select(item) {
setSelected(item)
}
return (
<div>
<div className={styles.selectWrapper}>
{arr.map(item => (
<div
key={item}
className={item === selected ? styles.selectItem_active : styles.selectItem_basic}
onClick={() => select(item)}
>
{item}
</div>
))}
</div>
{tabSet[selected]} // 当前标签页的展示内容
</div>
)
}
函数组件内使用useState Hook,通过selected变量来存放选中的标签名;
样式可灵活自行配置。
样式
记录一下简单的配置,使用的是语法是less
.selectWrapper{
display: flex;
height: 50px;
background: #F4F5F7;
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
div{
height: 100%;
padding: 0 40px;
line-height: 50px;
cursor: pointer;
}
}
.selectItem_active{
color: #FFFFFF;
background: #2D8CF6;
}
效果图
拓展: 不传入Tab页内容,使用a标签定位
情景
多个标签页共享使用同一个组件,或者tab标签名由后端传过来。
使用
const arr = ['城市概况', '城市历史', '地理位置']
function getSelect(item) { console.log(item) }
<Tab onChange={getSelect} arr={arr} />
<div id="城市概况"></div>
组件
import React, { useState } from 'react';
import styles from './component.less';
export default props => {
const { onChange, arr } = props;
const [selected, setSelected] = useState(arr[0]); // 当前选中的tab标签
function select(item) {
setSelected(item);
onChange(item)
}
return (
<div className={styles.selectWrapper}>
{Array.isArray(arr) &&
arr.map(item => (
<a
href={`#${item}`}
className={item === selected ? styles.selectItem_active : styles.selectItem_basic}
onClick={() => select(item)}
>
{item}
</a>
))}
</div>
);
};