Closed lulujianglab closed 5 years ago
由于项目的需要,最近开发了一些定制化的react组件,这篇文章主要介绍下呼出三级菜单的实现原理,支持鼠标悬浮呼出和鼠标点击呼出
在事件机制中,主要利用鼠标的一些事件来监听,具体如下:
利用onClick(鼠标点击),onMouseOver(鼠标进入),onMouseLeave(鼠标离开)来监听鼠标的变化,同时在state状态机中定义控制菜单出现或消失的状态标识,然后通过这些鼠标事件来改变相应的状态值
class Hovermenu extends PureComponent { constructor(props) { super(props) this.state = { show: true, currentIndex: null, currentApplicationIndex: null, currentTabIndex: null, } this.handleMouseOver = this.handleMouseOver.bind(this) this.handleTabMouseOut = this.handleTabMouseOut.bind(this) this.setcurrentIndex = this.setcurrentIndex.bind(this) this.setoverSvg = this.setoverSvg.bind(this) this.setleaveSvg = this.setleaveSvg.bind(this) this.handleClick = this.handleClick.bind(this) this.handleDataMenu = this.handleDataMenu.bind(this) } componentDidMount () { } handleMouseOver(e) { this.setState({ currentApplicationIndex: parseInt(e.currentTarget.getAttribute('index'), 10), currentTabIndex: parseInt(e.currentTarget.getAttribute('index'), 10) }) } handleTabMouseOut() { this.setState({ currentTabIndex : null, currentApplicationIndex: null }) } setcurrentIndex(e) { this.setState({ currentIndex : parseInt(e.currentTarget.getAttribute('index'), 10) }) } setoverSvg() { this.setState({ show : false }) } setleaveSvg() { this.setState({ show : true }) } handleClick() { this.setState({ currentIndex : null }) } // 处理菜单数据 将第三级菜单抽象成JSX handleDataMenu(arr) { const { currentIndex } = this.state return ( <ul className={styles.card}> { arr.map((item,index) => { return ( <a href='#' target="_blank" className={styles.text} key={item.name}> <li key={item.name} className={`${styles.item} ${currentIndex === index? styles.active : ''}`} index={index} onClick={this.setcurrentIndex} onMouseOver={this.setoverSvg} onMouseLeave={this.setleaveSvg} onFocus={() => 0}> {item.name} </li> </a> ) }) } </ul> ) } render () { const { currentTabIndex, currentApplicationIndex } = this.state const menuData = this.props.menu const title = this.props.title ? this.props.title : '下拉菜单' const { trigger }= this.props // 一级菜单name const applicationArr = menuData.map(item => { return item.name }) // 二级三级菜单数组 const tabArr = menuData.map(item => { return item.children }) // 一级菜单JSX const applicationList = ( applicationArr.map((item,index) => { if ( trigger === 'click' ) { return ( <div key={item} className={`${styles.item} ${currentApplicationIndex === index? styles.active : ''}`} index={index} onClick={this.handleMouseOver} onFocus={() => 0}> <div className={styles.title}>{item}</div> </div> ) } else { return ( <div key={item} className={`${styles.item} ${currentApplicationIndex === index? styles.active : ''}`} index={index} onMouseOver={this.handleMouseOver} onFocus={() => 0}> <div className={styles.title}>{item}</div> </div> ) } }) ) // 二三级菜单分层处理 const tabList = ( tabArr.map((item,index) => { return ( <div key={item[0].id} className={`${styles.item} ${currentTabIndex === index? styles.layer : styles.hidden}`} index={index} onMouseOver={this.handleMouseOver} onMouseOut={this.handleTabMouseOut} onClick={this.handleClick} onFocus={() => 0} onBlur={() => 0}> <Tabs defaultActiveKey="1" onChange={this.callback}> { item.map((element) => { return <TabPane key={element.id} tab={element.name}>{this.handleDataMenu(element.children)}</TabPane> }) } </Tabs> </div> ) }) ) return ( <Card title={title} bordered={false} className={styles.main}> <div className={styles.content}> {applicationList} </div> {tabList} </Card> ) } } export default Hovermenu
除了事件机制控制状态变化外,我们还需要在样式中设置父类和子类的position值,父类值为relative,子类值为absolute,同时为使悬浮菜单在最前端显示,菜单的css中需要加入层级控制z-index(数值越大,越靠前端)
同时需要注意的是,在hover判断时,需要在其中通过控制display来控制显示与否
如下面的.hidden { display: none }
.hidden { display: none }
.main { position: relative; .content { ... } .layer { position: absolute; z-index: 1050; left: 0; top: 144px; width: 100%; background-color: #f0f2f5; box-shadow: 0 2px 4px 0 #D9D9D9; border-radius: 2px; :global { .ant-tabs-nav .ant-tabs-tab { color: #666; } } .card { ... } } .hidden { display: none; } }
可见我的另一篇博客通过npm发布的第一个React组件的实践过程
前端React的三级菜单组件
由于项目的需要,最近开发了一些定制化的react组件,这篇文章主要介绍下呼出三级菜单的实现原理,支持鼠标悬浮呼出和鼠标点击呼出
事件机制
在事件机制中,主要利用鼠标的一些事件来监听,具体如下:
利用onClick(鼠标点击),onMouseOver(鼠标进入),onMouseLeave(鼠标离开)来监听鼠标的变化,同时在state状态机中定义控制菜单出现或消失的状态标识,然后通过这些鼠标事件来改变相应的状态值
样式设置
除了事件机制控制状态变化外,我们还需要在样式中设置父类和子类的position值,父类值为relative,子类值为absolute,同时为使悬浮菜单在最前端显示,菜单的css中需要加入层级控制z-index(数值越大,越靠前端)
同时需要注意的是,在hover判断时,需要在其中通过控制display来控制显示与否
如下面的
.hidden { display: none }
封装
可见我的另一篇博客通过npm发布的第一个React组件的实践过程
Github Repo
前端React的三级菜单组件