React实现TabBar切换,带动画效果
<TabBar defaultKey={1} heardList={[ {text: '基本信息',key:1}, {text: '项目周报',key:2}, {text: '附件信息',key:3} ]} />
import React, {PureComponent} from 'react'; import styled from "styled-components"; import PropTypes from 'prop-types' export default class TabBar extends PureComponent{ static propTypes = { tabs:PropTypes.array.isRequired } static defaultProps ={ tabs:[ { text:'标题1', key:1 }, { text:'标题2', key:2 }, { text:'标题3', key:3 }, ] } constructor(props) { super(props);this.state = { checkedTab:props.defaultKey, checkedPosition:0, } } onChange = (checkedTab, index) => { this.setState({checkedTab:checkedTab.key, checkedPosition: ((100 / this.props.tabs.length) * index) + '%'}); this.props.onChange(checkedTab) }; render() { const { tabs } = this.props; const {checkedTab, checkedPosition} = this.state; return ( <Root> <div className={'taberContainer'}> <div className={'taber'}> {tabs.map((item, index) => ( <div key={item.key} className={checkedTab === item.key ? 'tabItemChecked' : 'tabItem'} onClick={() => this.onChange(item, index)} > {item.text} </div> ))} </div> <div className={'tabBar'} style={{ // transform: `translate3d(${checkedPosition}, 0px, 0px)`, width: (100 / tabs.length) + '%', left: checkedPosition }} /> </div> </Root> ) } } const Root = styled.div` background: rgba(255, 255, 255, 1); box-sizing: border-box; .taberContainer { position: relative; box-sizing: border-box; .taber { display: flex; box-sizing: border-box; .tabItem,.tabItemChecked { box-sizing: border-box; font-size: 14px; font-family: PingFangSC-Regular; font-weight: 400; color: rgba(51, 51, 51, 1); text-align: center; width: 33.33%; padding: 12px 17px; cursor: pointer; border-bottom: 1px solid rgba(232, 232, 232, 1); // transition: border 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); } .tabItemChecked{ color: rgba(0, 155, 255, 1); } } .tabBar { position: absolute; bottom: 0px; box-sizing: border-box; background-color: #1890ff; border: 1px #108ee9 solid; transition: top .3s cubic-bezier(0.35, 0, 0.25, 1),left .3s cubic-bezier(0.35, 0, 0.25, 1), color .3s cubic-bezier(0.35, 0, 0.25, 1),width .3s cubic-bezier(0.35, 0, 0.25, 1) } } } `