【发布时间】:2018-05-09 03:47:48
【问题描述】:
【问题讨论】:
-
我尝试了语义 UI,但我没有找到任何这样的下拉菜单
标签: reactjs ecmascript-6
【问题讨论】:
标签: reactjs ecmascript-6
您可以使用一个父组件将值保持在其状态并切换列表项。然后,您可以为每个列表项创建组件,该组件将使活动属性保持在您可以在单击时切换的状态。
class ListItem extends React.Component {
constructor(props) {
super(props);
this.state = {active: false}
}
render() {
return (
<a
onClick={() => {
this.setState(prevState => {
let newState = !prevState.active;
this.props.handleClick(newState, this.props.value);
return {active: newState}
})
}}
className={!this.state.active ? '' : 'selected'}
href="#">
{this.props.value}</a>
)
}
}
class Select extends React.Component {
constructor(props) {
super(props);
this.state = {
showList: false,
value: []
}
this.handleItemClick = this.handleItemClick.bind(this)
}
componentDidMount() {
document.addEventListener('mousedown', (e) => {
if(!this.node.contains(e.target)) {
this.setState({showList: false})
}
})
}
componentWillUnmount() {
document.removeEventListener('mousedown');
}
renderValue() {
let {value} = this.state;
if(!value.length) return "Select..."
else return value.join(', ')
}
toggleList() {
this.setState(prevState => ({showList: !prevState.showList}))
}
handleItemClick(active, val) {
let {value} = this.state;
if(active) value = [...value, val]
else value = value.filter(e => e != val);
this.setState({value})
}
render() {
return (
<div
ref={node => this.node = node}
className="select">
<button onClick={this.toggleList.bind(this)}>
<span className="select_value">
{this.renderValue()}
</span>
</button>
<div
className={"select_list " + (!this.state.showList && 'hide')}>
<ListItem handleClick={this.handleItemClick} value="Lorem" />
<ListItem handleClick={this.handleItemClick} value="Ipsum" />
<ListItem handleClick={this.handleItemClick} value="Dolor" />
</div>
</div>
)
}
}
ReactDOM.render(
<Select />,
document.getElementById('container')
);
button {
background: white;
width: 100%;
padding: 10px 15px;
border: 1px solid rgba(0, 0, 0, .1);
border-radius: 5px;
cursor: pointer;
text-align: left;
}
.select_list {
width: 100%;
background: white;
border: 1px solid rgba(0, 0, 0, .1);
border-radius: 5px;
}
.select_list a {
padding: 10px 15px;
display: flex;
color: black;
text-decoration: none;
position: relative;
align-items: center;
}
.select_list a:before {
width: 15px;
height: 15px;
content: '';
border: 1px solid rgba(0, 0, 0, .1);
border-radius: 5px;
margin-right: 10px;
display: block;
}
.select_list a.selected:before {
background: #0493D1;
content: '✓';
color: white;
font-size: 11px;
text-align: center;
line-height: 15px;
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
【讨论】:
componentDidMount 上使用的文档上的事件侦听器,这是当您在其外部单击时关闭模式的选项。但是我不能确切地告诉你为什么没有你的代码示例会发生这种情况。应该在componentWillUnmount 上删除事件侦听器,因此如果您无法像现在这样修复它,您可以删除该功能或尝试以其他方式实现它。
语义 UI 反应方法
经过大量挖掘,我发现了 eugenetumachov 和 Semantic-UI 开发人员之间的旧对话(?)。其中一位用户提供了非常有用的代码,该代码使用 Semantic-UI 的下拉组件回答了这个问题。
这是通过使用 Dropdown 的 Dropdown.Menu 和 Dropdown.Item 来完成的。然后通过地图循环您的选项以创建复选框。唯一的缺点是解决方法似乎不允许滚动,并且需要更多的 CSS。此外,根据 CSS,如果您双击下拉菜单,复选框项目的背景颜色可能会变为透明,并且下拉菜单会在鼠标悬停时折叠。您可以通过对 Dropdown.Menu 和 Dropdown.Item 使用类或样式属性来绕过透明度问题。
Semantic-UI 开发人员对此类问题的回答似乎是一个简单的“否”或一个
活动项目会自动从下拉菜单中删除。因此,您不能在菜单中显示某个项目的“已选中”状态。
您可以从 Input 创建一个类似的组件作为触发器 一个包含菜单或复选框列表的弹出窗口。
【讨论】: