實現經過鼠標拖拽一個後臺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)