我尝试使用以下条件在React (v 16.5)
中创建折叠和展开侧边菜单-
页面加载时,第一项(圆形)将处于展开视图中。一个项目可以一次扩展,例如,如果用户单击第二个项目(“规范”),则第一个项目将折叠。我还希望在收起/展开交易过程中使用一些CSS动画,例如平稳地向下/向上调整每个项目的主体部分并更改箭头图标。我的方法是动态地在每个项目(sidebar-nav-menu-item
)上添加/删除CSS类,例如-
sidebar-nav-menu-item item-active
因此,当某个项目处于展开视图时,它应该像上面的类,并在折叠视图中删除item-active
。默认情况下,当项目处于折叠模式时,div
主体(sidebar-nav-menu-item-body)应通过CSS隐藏。
import React, { Component } from 'react';
className SidebarNavs extends React.Component{
constructor(props) {
super(props);
}
render() {
return(
<div className="sidebar-nav">
<div className="sidebar-nav-menu">
<div className="sidebar-nav-menu-item" data-id="circulars">
<div className="sidebar-nav-menu-item-head" onClick={this.handleExpandCollaps}>
<div className="sidebar-nav-menu-item-head-title">Circulars</div>
<div className="sidebar-nav-menu-item-head-help">
<button type="button" className="btn-help" onClick={this.moreInfoClick}>View more info</button>
</div>
<div className="sidebar-nav-menu-item-head-icon">
<i className="fa fa-caret-down" aria-hidden="true"></i>
</div>
</div>
<div className="sidebar-nav-menu-item-body">BODY CONTENT HERE</div>
</div>
<div className="sidebar-nav-menu-item" data-id="specifications">
<div className="sidebar-nav-menu-item-head" onClick={this.handleExpandCollaps}>
<div className="sidebar-nav-menu-item-head-title">Specifications</div>
<div className="sidebar-nav-menu-item-head-help">
<button type="button" className="btn-help" onClick={this.moreInfoClick}>View more info</button>
</div>
<div className="sidebar-nav-menu-item-head-icon">
<i className="fa fa-caret-down" aria-hidden="true"></i>
</div>
</div>
<div className="sidebar-nav-menu-item-body">BODY CONTENT HERE</div>
</div>
<div className="sidebar-nav-menu-item" data-id="wo">
<div className="sidebar-nav-menu-item-head" onClick={this.handleExpandCollaps}>
<div className="sidebar-nav-menu-item-head-title">Work Orders</div>
<div className="sidebar-nav-menu-item-head-help">
<button type="button" className="btn-help" onClick={this.moreInfoClick}>View more info</button>
</div>
<div className="sidebar-nav-menu-item-head-icon">
<i className="fa fa-caret-down" aria-hidden="true"></i>
</div>
</div>
<div className="sidebar-nav-menu-item-body">BODY CONTENT HERE</div>
</div>
</div>
</div>
)
}
}
export default SidebarNavs;
CSS:
.sidebar-nav-menu-item{
display:block;
}
.sidebar-nav-menu-item-body{
display:none;
}
.sidebar-nav-menu-item.item-active .sidebar-nav-menu-item-body{
display:block;
}
答案 0 :(得分:1)
您应该使用状态变量来显示可折叠项为活动/非活动。
我对您的代码做了一些修改,以使其符合您的要求。
class App extends Component {
constructor() {
super();
this.state = {
activeCollapse: 'circulars'
};
}
handleExpandCollaps = (name) => {
if (this.state.activeCollapse === name) {
this.setState({ activeCollapse: '' })
} else {
this.setState({ activeCollapse: name })
}
}
moreInfoClick = (e) => {
e.stopPropagation();
console.log("clicked");
}
render() {
return (
<div>
<div className="sidebar-nav">
<div className="sidebar-nav-menu">
<div className={`sidebar-nav-menu-item ${this.state.activeCollapse === "circulars" ? 'item-active' : ''}`} onClick={() => this.handleExpandCollaps("circulars")} data-id="circulars" >
<div className="sidebar-nav-menu-item-head">
<span className="sidebar-nav-menu-item-head-title">Circulars</span>
<span className="sidebar-nav-menu-item-head-help">
<button type="button" className="btn-help" onClick={this.moreInfoClick}>View more info</button>
</span>
</div>
<div className="sidebar-nav-menu-item-body">BODY CONTENT HERE</div>
</div>
<div className={`sidebar-nav-menu-item ${this.state.activeCollapse === "specifications" ? 'item-active' : ''}`} onClick={() => this.handleExpandCollaps("specifications")} data-id="specifications">
<div className="sidebar-nav-menu-item-head">
<span className="sidebar-nav-menu-item-head-title">Specifications</span>
<span className="sidebar-nav-menu-item-head-help">
<button type="button" className="btn-help" onClick={this.moreInfoClick}>View more info</button>
</span>
</div>
<div className="sidebar-nav-menu-item-body">BODY CONTENT HERE</div>
</div>
<div className={`sidebar-nav-menu-item ${this.state.activeCollapse === "wo" ? 'item-active' : ''}`} onClick={() => this.handleExpandCollaps("wo")} data-id="wo">
<div className="sidebar-nav-menu-item-head">
<span className="sidebar-nav-menu-item-head-title">Work Orders</span>
<span className="sidebar-nav-menu-item-head-help">
<button type="button" className="btn-help" onClick={this.moreInfoClick}>View more info</button>
</span>
</div>
<div className="sidebar-nav-menu-item-body">BODY CONTENT HERE</div>
</div>
</div>
</div>
</div>
);
}
}
注意:我已将CSS
用于font-awesome
图标。希望您已添加font-awesome
答案 1 :(得分:0)
要做到这一点,我将使用React.useState
,因为它是控制和制作动画的小状态,所以我会使用CSS:
该组件如下所示:
function SidebarNavs() {
const [activeItem, setActiveItem] = React.useState(1);
return (
<div className="sidebar-nav">
<div className="sidebar-nav-menu">
<SidebarItem
title="Circulars"
setActiveItem={setActiveItem}
index={1}
activeItem={activeItem}
>
Sidebar Content Here
</SidebarItem>
<SidebarItem
title="Specifications"
setActiveItem={setActiveItem}
index={2}
activeItem={activeItem}
>
Sidebar Content Here
</SidebarItem>
<SidebarItem
title="Specifications"
setActiveItem={setActiveItem}
index={3}
activeItem={activeItem}
>
Work Orders
</SidebarItem>
</div>
</div>
);
}
function SidebarItem({ title, children, setActiveItem, activeItem, index }) {
const expanded = activeItem === index;
const cls = "sidebar-nav-menu-item " + (expanded ? "item-active" : "");
return (
<div className={cls}>
<div className="sidebar-nav-menu-item-head">
<div className="sidebar-nav-menu-item-head-title">{title}</div>
<div className="sidebar-nav-menu-item-head-help">
<button
type="button"
className="btn-help"
onClick={() => setActiveItem(index)}
>
View more info
</button>
</div>
<div className="sidebar-nav-menu-item-head-icon">
<i className="fa fa-caret-down" aria-hidden="true" />
</div>
</div>
<div className="sidebar-nav-menu-item-body">{children}</div>
</div>
);
}
CSS看起来像这样:
.sidebar-nav-menu-item {
border: 1px solid #CCC;
margin-bottom: 20px;
}
.sidebar-nav-menu-item .sidebar-nav-menu-item-body {
overflow: hidden;
max-height: 0;
transition: all linear 0.5s;
}
.sidebar-nav-menu-item.item-active .sidebar-nav-menu-item-body {
max-height: 100px;
transition: all linear 0.5s 0.3s;
}