带反应的动态JQuery菜单
我想用React(ES6)创建一个动态JQuery菜单。我遵循JQuery菜单示例(https://jqueryui.com/menu/),但其中的所有示例都创建静态菜单。它没有解释如何更改菜单项,如更新标签或启用。另外,我不想最终在React中实现新的菜单。带反应的动态JQuery菜单
我有我的菜单项,它假定嵌套级别的JSON数组。
let simple= [{
disabled: true,
label: "Item1"
},
{
label: "Item2"
},
{
label: "-"
},
{
label: "Item3"
},
{
label: "Item4",
children: [
{
label: "Sub Item1"
},
{
label: "Sub Item2"
},
{
label: "Sub Item3"
}
]
}];
我想要更新标签或直接在菜单中完成任何json项目的显示。我需要避免手动DOM操作,因为这是一种容易出错的方法。
React中的动态操作对于突变功能来说很简单。首先,我想你已经这样做,你需要导入的JQuery库需要
import $ from 'jquery';
import 'jquery-ui/ui/core';
import 'jquery-ui/ui/widgets/menu';
而且你需要引用您的菜单的反应成分如下。动态生命周期将作为反应状态处理(https://facebook.github.io/react/docs/state-and-lifecycle.html)。我们使用一个状态,例如menuItems来管理JSON对象/数组。您可以看到该位置设置为绝对。没有这个,你的菜单将会导致你的整个文档展开,除非这是你想要的行为。
<ul ref="menu" style={{display: "none", position: "absolute"}}>
{this.state.menuItems.map(this.processMenuEntry.bind(this, 0))}
</ul>
processMenuEntry方法的实现如下。当然你可以更新这个方法来匹配任何不同的JSON结构。 我会建议使用className的一个小改动:“ui-state-disabled”而不是disabled:true。因此,您将有更多选项来自定义您的样式,而不仅仅是启用/禁用。下面的方法假定嵌套级别,以零开头,就像上面代码片段中的初始调用一样。确保为子组件分配密钥很重要。
processMenuEntry(level, entry, idx){
let id= "menu"+ level+ "_"+ idx;
if(!entry.className){
entry.className= "";
}
let children= entry.children;
let child;
if(children && children.length){
child= <li className= {entry.className} key= {id}><div>{entry.label}</div><ul>{children.map(this.processMenuEntry.bind(this, level+1))}</ul></li>;
}else{
child= <li className= {entry.className} key= {id}><div>{entry.label}</div></li>;
}
return child;
}
确保在你的构造,使这个电话,所以你的方法将你的反应成分在HTML
this.processMenuEntry= this.processMenuEntry.bind(this);
在componentDidMount添加此代码段相同的情况下,才能启动菜单API工作,除了你的点击处理程序。
componentDidMount(){
$(this.refs.menu).menu({
select: function(event, ui) {
//do
}
});
}
现在,例如,如果要禁用菜单中的第二项,则可以简单地执行该操作。
simple[1].className= "ui-state-disabled";
this.setState({"menuItems": simple});
您可以和设定一个完全不同的JSON数组,并做出反应将它
this.setState({"menuItems": [{
label: "Some new Item1"
}]});
使用的护理“ - ”作为一个标签将一个分隔符添加到您的菜单JQuery菜单API的设计。
最后,在处理菜单切换或在外部点击时隐藏菜单,您可以查看下面的代码片段。当然,你可以根据你的工作进行修改。我在下面假设我们在点击锚点时切换菜单。检查用户在菜单外单击是否仅在菜单可见时才添加。
<a href="https://*.com" onClick={this.toggleMenu}>Test</a>
componentWillUnmount(){
this.stopMenuListeners();
}
stopMenuListeners(){
$(document).off("click.menuOutsideClicks");
}
toggleMenu(event){
let menu= $(this.refs.menu);
let visible= !menu.is(':visible');
menu.slideToggle("fast");
this.stopMenuListeners();
if(visible){
setTimeout(()=>{
this._handler= $(document).on("click.menuOutsideClicks", (event)=>{
if(!$(event.target).closest(menu).length){
menu.slideUp('slow').hide();
this.stopMenuListeners();
}
});
});
}
event.stopPropagation();
event.preventDefault();
}