React拖拽组件react-sortable-hoc给子组件添加onClick失效问题
实现使用 react-sortable-hoc 插件
基本使用先见官网: https://clauderic.github.io/react-sortable-hoc/#/basic-configuration/basic-usage?_k=0ronzp
github地址:https://github.com/clauderic/react-sortable-hoc/blob/master/examples/basic.js
点击事件绑定不上的解决方案:https://github.com/clauderic/react-sortable-hoc/issues/206
原因:react-sortable-hoc已经使用了onClick事件。因此,其中的任何内容都无法使用onClick。
演示一种解决方案: 您可以给 SortableContainer 组件上 使用distance prop设置触发排序之前要拖动的最小距离(例如,您可以设置10px的距离,例如:distance = {10}), 这时候直接点击就不会立即触发SortableContainer 上的点击事件。
从而解决问题。
拖拽+点击 效果图 :
先安装包
npm install react-sortable-hoc --save
主要部分代码演示:
import React, {Component} from 'react'; import {render} from 'react-dom'; import {Tooltip} from 'antd'; import IconFont from '../IconFont'; //IconFont //拖拽 import {sortableContainer, sortableElement} from 'react-sortable-hoc'; import arrayMove from 'array-move'; const SortableContainer = sortableContainer( (props) => <ul {...props}>{props.children}</ul> ); const SortableItem = sortableElement( (props) => <li {...props}>{props.children}</li> ); //拖拽end class App extends Component { state = { Routes: [ { "title": "企业管理", "icon": "icont3a", "isRenderMenu": true, "children": [ { "title": "企业通讯录", "icon": "icona23", "children": [ { "path": "/admin/corporateBook", "exact": false, "showInMenu": true, "title": "企业通讯录", "icon": "" } ] } ] }, { "title": "智能人事", "icon": "icont1a", "isRenderMenu": true, "children": [ { "title": "组织架构", "icon": "", "children": [ { "path": "/admin/aptitudeHR/Framework", "exact": false, "showInMenu": true, "title": "部门/员工", "icon": "" }, { "path": "/admin/aptitudeHR/PostManage", "exact": false, "showInMenu": true, "title": "职位管理", "icon": "" }, ] } ] } ], }; onSortEnd = ({oldIndex, newIndex}) => { this.setState(({items}) => ({ items: arrayMove(items, oldIndex, newIndex), })); }; render() { return ( <SortableContainer //使子项点击事件可以正常执行的关键代码 distance = {10} onSortEnd={this.onSortEnd}> { this.state.Routes.map((item, index) => ( <SortableItem key={`item-${index}`} index={index} value={index} > <ul className='left-menu global-timestamp-1587610943136-left-menu'> <li className={this.state.currentLeftMenu === index ? 'active' : ''} //点击事件可以正常执行 onClick={this.handleGo.bind(this, item, index)}> <Tooltip placement="right" title={item.title} mouseEnterDelay='0'> <div style={{textAlign: 'center'}}> <IconFont type={item.icon}/> </div> </Tooltip> </li> </ul> </SortableItem> )) } </SortableContainer> ); } } render(<App />, document.getElementById('root'));
这样就可以了。
哦,注意 拖拽时可能会造成样式丢失,原因是你的样式可能存在父级,因为拖拽时 react-sorttable-hoc 会帮我们复制一份拖拽的dom节点,放到body下,所以有父级样式就访问不到了。可以把样式直接写在body,注意class命名,别和其他冲突了。
我是这样写的:
//左侧拖拽菜单 ul.global-timestamp-1587610943136-left-menu.left-menu { margin-top: 10px; display: flex; flex-direction: column; align-items: center; width:64px; font-size: 20px; color: rgba(255,255,255,.5); li { display: flex; flex-direction: column; justify-content: center; width: 40px; height: 40px; border-radius: 50%; margin-bottom: 28px; cursor: pointer; } li:hover{ color: rgba(255,255,255,.9); } li.active { color: rgba(255,255,255,1); background:rgba(255,255,255,0.12); } }
结束结束。