react 模擬從後臺獲取選單資料,點選頂部選單切換介面的筆記
阿新 • • 發佈:2018-12-14
本文是基於Ant design Pro 2.0做的筆記,官方提供的demo(官方demo下載地址),路由是程式配置的,不能滿足專案需求,所以在研究過程中,把所遇到的問題,做一個筆記,最終效果圖如下:
一:需求描述
1 從介面獲取選單,替換預設demo的選單。
由於只是測試,所以並沒有使用service去呼叫介面,而是在model層設定選單陣列,選單陣列結構如下:
[{"id": "10", "name": "美食", "parentId": "父節點id", "isShow": "1",locale: "menu.ms"},{ "id": "100", "name": "中餐", "parentId": "10", "isShow": "1", href: "xxx", path: "xxx", locale: "menu.test.zc" },{ "id": "1001", "name": "川菜", "parentId": "100", "isShow": "1", href: "xx", path: "xx", component: "xx", locale: "menu.test.zc.M1001" },]
2 修改預設佈局
預設佈局頂部是沒有選單項的,我重新定義了佈局,佈局js取名為NewLayout.js,頂部js取名為NewHeaderView.js,因為我重新建立了NewLayout.js,所以需要修改config/router.config.js的佈局配置.
export default [{ path: '/', component: '../layouts/NewLayout',//將BasicLayout更改為NewLayout }]
修改NewLayout.js對頂部選單的引用
const layout = ( <Layout> {isTop && !isMobile ? null : ( <SiderMenu logo={logo} Authorized={Authorized} theme={navTheme} onCollapse={this.handleMenuCollapse} menuData={menuData} isMobile={isMobile} {...this.props} /> )} <Layout style={{ ...this.getLayoutStyle(), minHeight: '100vh', }}> <div style={{ height: "100px", background: "#fff" }}> <NewHeaderView {...this.props} /> </div> <Content style={this.getContentStyle()}> <Authorized authority={routerConfig && routerConfig.authority} noMatch={<Exception403 />} > {children} </Authorized> </Content> <Footer /> </Layout> </Layout> );
3 建立頂部選單
首先需要在NewHeaderView.js,componentDidMount方法呼叫Model,獲取選單資料。
dispatch({ type: "testModel/getMenuData", callback: (data) => { this.setState({ topMenuData: data, }); });
建立頂部選單
getMenu=(menuData)=>{ let result = []; for(let data of menuData){ if(data.children){ let childrenData = this.getMenu(data.children); result.push(<SubMenu title={<span className="submenu-title-wrapper"><Icon type="setting" />{data.value}</span>}>{childrenData}</SubMenu>); }else{ result.push(<Menu.Item key={data.key}><Icon type="mail" />{data.value}</Menu.Item>); } } return result; }; render() { let {topMenuData} = this.state; if(!topMenuData){ return ""; } console.log(this.TAG,"topMenuData ",topMenuData); let data = []; topMenuData.forEach(function(value,index,parData){ if(value.parentId=="0"){ data.push({"key":value.id,"value":value.name}); } }); let menuArr = this.getMenu(data); return ( <Menu selectedKeys={[this.state.current]} mode="horizontal" onClick={this.menuHandleClick}> {menuArr} </Menu> ); };
4 頂部選單點選後,切換到當前選單下,第一個子節點下的第一個選單介面。
獲取被點選選單,第一個子節點下的第一個選單資料。
menuHandleClick = (e) => { //console.log('NewHeaderView:menuHandleClick ', e); this.setState({ current: e.key, }); const {dispatch} = this.props; let {topMenuData} = this.state; //獲取被點選選單的所有子資料 const treeData = jsonToTreeJson(topMenuData,e.key); //第一個子節點下的第一個選單資料 const childJson = getChiledByMenuIndex(treeData); console.log(this.TAG, "menuHandleClick_Child:", childJson); let param = {key:e.key,url:childJson.url};
//呼叫model,實現跳轉到指定的url dispatch({type:"testModel/curClickKey",payload:param}); }
實現介面跳轉的model.
*curClickKey({payload,callback},{call,put}){ console.log("Model:",payload); let curClickKey = payload.key; yield put({ type:"setCurClickKey", payload:curClickKey, }); yield put(routerRedux.replace(payload.url || '/')); } reducers: { setCurClickKey(state, action) { return { ...state, curClickKey: action.payload, } }, }
5 修改本地路由配置檔案(config/router.config.js),由於是多級選單 ,注意選單陣列的格式。
{ path: '/', redirect: '/test/zc/M1001' }, { path:"/test", name: 'test', icon: 'dashboard', routes:[{ path:"/test/zc", name:"zc", routes:[{ path: '/test/zc/M1001', name: 'analysis', component: './test/zc/M1001', },{ path: '/test/zc/M1002', name: 'analysis', component: './test/zc/M1002', }] },{ path:"/test/xc", name:"xc", routes:[{ path: '/test/xc/M1003', name: 'analysis', component: './test/xc/M1003', },{ path: '/test/xc/M1004', name: 'analysis', component: './test/xc/M1004', }] },{ path:"/test/fj", name:"fj", routes:[{ path: '/test/fj/M1005', name: 'analysis', component: './test/fj/M1005', },{ path: '/test/fj/M1006', name: 'analysis', component: './test/fj/M1006', }] },{ path:"/test/ly", name:"ly", routes:[{ path: '/test/ly/M1007', name: 'analysis', component: './test/ly/M1007', },{ path: '/test/ly/M1008', name: 'analysis', component: './test/ly/M1008', }] },{ path:"/test/yk", name:"yk", routes:[{ path: '/test/yk/M1009', name: 'analysis', component: './test/yk/M1009', },{ path: '/test/yk/M1010', name: 'analysis', component: './test/yk/M1010', }] },{ path:"/test/aqy", name:"aqy", routes:[{ path: '/test/aqy/M1011', name: 'analysis', component: './test/aqy/M1011', },{ path: '/test/aqy/M1012', name: 'analysis', component: './test/aqy/M1012', }] }] }
以上是做的筆記,如有錯誤,請指出來, 完整程式碼下載地址:https://github.com/jlq023/react_remote_get_menu