实现经过鼠标拖拽一个后台API到Form实现自动加载API因此的字段成表单
拖动组件采用react-dnd
这个插件,数据交互和页面更新等等使用Hooks实现
Hooks官方文档https://react.docschina.org/docs/hooks-intro.html
ReactDnd官方文档http://react-dnd.github.io/react-dnd/html
http://jianjiacheng.com/json/swagger.jsonhtml5
https://github.com/jianjiachenghub/ReactHooksDnD.gitreact
组件须要使用useDrag这个dnd插件封装好的hook
而后将hook返回的函数赋值给DOM的ref属性进行操做
Items 是拖拽数据的表现形式,用 Object 来表示。ios
import React from 'react' import { useDrag } from 'react-dnd' import { Menu, Icon ,Button} from 'antd'; const DragBox = ({ name, data }) => { const [{ opacity }, drager] = useDrag({ item: { name, type:'dragBox',data}, collect: monitor => ({ opacity: monitor.isDragging() ? 0.4 : 1, }), }) return ( <div ref={ drager }><Button value="large" type="dashed" block>{name}</Button></div> ) } export default DragBox
accept属性指定只能接受拖动的item里type为dragBox的
drop是一个监听滑动完成的一个回调git
import React from 'react' import { useDrop } from 'react-dnd' import CreactForm from "./CreactForm" const style = { minHeight: 780, height: '100%', border: '1px dashed black' } const Dustbin = ({onDrop,data}) => { const [{ isOver, canDrop }, drop] = useDrop({ accept: 'dragBox', drop: onDrop, collect: monitor => ({ isOver: monitor.isOver(), canDrop: monitor.canDrop(), }), }) const getForm = (data)=>{ if (Object.keys(data).length !== 0) { const {data:{properties}} = data return <CreactForm data={properties}/> } } return ( <div ref={drop} style={{ ...style}}> {getForm(data)} </div> ) } export default Dustbin
在这个数据的JS代码部分解析好数据并传递给子组件github
<Layout> <Sider> {returnData.map(({ name, data }, index) => ( <DragBox name={name} data={data} key={index} /> ))} </Sider> <Content> <Dustbin onDrop={item => handleDrop(item)} data={dropData} /> </Content> </Layout>
import React from 'react' import ReactDOM from 'react-dom' import DndMenu from './menu' import { DndProvider } from 'react-dnd' import HTML5Backend from 'react-dnd-html5-backend' function Dnd() { return ( <div className="App"> <DndProvider backend={HTML5Backend}> <DndMenu /> </DndProvider> </div> ) } export default Dnd
useEffect(() => { getData() },[]);
const getData = async () => { const result = await axios( `${GLOBAL_URL}/list` ); console.log(result) const data = result.data[0] const api = getKey(data.apiPath) getTreeData(api,data.apiPath) const originalData = getOriginalData(data.apiPath,data.apiDefinitions) setData(originalData) } const [returnData, setData] = useState([]);//根据returnData去渲染UI
之前使用Class语法时在子组件内部使用this.props能够拿到父组件传递的数据
而如今的函数式语法能够直接在子组件的参数使用解构赋值拿到上层传递的数据json
const DragBox = ({ name, data }) => { } function DndMenu(props) { return ( <DragBox name={name} data={data} key={index} /> ) }
之前的Class语法在组件内部想要调用Ant里面Form的函数只须要类修饰器@后
就能在组件内部使用this.props调用到form的APIaxios
@Form.create() @connect(({ usersModal, basicdata, loading }) => ({ usersModal, basicdata, loading : loading.models.usersModal, loadingEditFlag : loading.effects['usersModal/saveEditFlag'], loadingUpdate : loading.effects['usersModal/UpdateUser'], loadingGet : loading.effects['usersModal/getUser'], loadingAdd : loading.effects['usersModal/addUser'], })) class UserDetail extends PureComponent { }
如今则能够再导出组件的时候直接将组件传入Form.create()返回的函数api
export default Form.create()(DndMenu)