1. 程式人生 > >react 模擬從後臺獲取選單資料,點選頂部選單切換介面的筆記

react 模擬從後臺獲取選單資料,點選頂部選單切換介面的筆記

 本文是基於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