Dva: 关于在dva下,动态路由及tabbar动态加载的问题

Created on 19 Jan 2017  ·  7Comments  ·  Source: dvajs/dva

当前,我的结构是这样的:

路由结构(src/router.js)

.....
import Home from './routes/home';
import Organization from './routes/organization';
import         Member from './routes/organization/routes/member';
import Partybuild from './routes/partybuild';
import Dynamic from './routes/dynamic';
import Test from './routes/test';
......
export default function({ history, app }) {
    const routes = {        
        childRoutes: [
            {
                ...Home(app),
                indexRoute: { onEnter: (nextState, replace) => replace('organization') },          
                childRoutes: [  
                    Organization(app),  
                    Partybuild(app),  
                    Dynamic(app), 
                    Test(app),               
                ], 
            },  
            Member(app),        
        ],
    }; 

  return <Router history={ history } routes={ routes } />;
}

说明: XXXX(app) ,是为了给动态加载路由,传递app对象,用于app.model注册.

Home的结构:(src/routers/home/index.js


return (
            <div className="home">
                {this.props.children} 
                <MyTabbar {...MyTabbarProps} /> 
            </div>
        );

说明: 结合路由的结构, 能看出首页是1个沉底tabbar4个item,动态加载4个子路由.实现的切换.

动态加载路由的例子 (src/routers/organizaiton/index.js)

export default (app)=>{
    const nameSpace= "organization";
    return {
        path: nameSpace,
        name: nameSpace,

        getComponent(nextState, cb) {
            require.ensure([], (require) => {

                if(!app._models.some(val=>(val.namespace ===  nameSpace ))) {
                    app.model(require('./Model.js'));
                };

                cb(null, require('./Page.js'));
            },"OrganizationPage")      
        },
    }
}

说明: 结合路由的结构, 能看出首页是1个沉底tabbar4个item,动态加载4个子路由.实现的切换.

我希望的结果是:

  1. 打开首页, 底部的tabbar管理切换4个子应用,
  2. 点击任何一个子应用的次级页面, 其应用均没有tabbar了.
    > 因此, 在路由结构里面的member(app), 写到了子路由外,脱离了tabbar的父组件的包含.

我的问题是:

这样写路由, 看不出member(app)其实是Organization的子页面. 所以我感觉我这么写很不优雅呀. (我的理解好的代码一定是优雅的,如果混乱么有节奏就有问题.).

期望: 请给指出一些问题, 指导一下,让这个路由结构更清晰

question

Most helpful comment

深层次嵌套的依旧渲染不出来.

是否是因为 html 文件里引用的是 index.js,改成 /index.js 试试?昨天内网也有个同学遇到了这个问题。

All 7 comments

补充,还是没有搞定,react-router官方动态路由写法中, 次级路由的渲染问题.

> 就是可以访问了, 但是页面不渲染.

原因是es5和es6的 export的写法区别导致(真隐蔽) , 找到的解决办法是:

  1. es6写法中增加default:
 cb(null, require('./Page.js')) 写成 cb(null, require('./Page.js').default); 
  1. 使用插件解决:babel-plugin-add-module-exports
[babel-plugin-add-module-exports]: (https://github.com/59naga/babel-plugin-add-module-exports)

### 结果:1方案没有反应, 2方案,在dva里面我不会配置这个插件)

使用 roadhog 的话,默认已加载 babel-plugin-add-module-exports

深层次嵌套的依旧渲染不出来.

@xttianma 是否是报The root route must render a single element错误?
用roadhog不需要require().default, 组件文件里面不能export多个, 所以不要误require了index之类的文件

我的路由结构是这样的

src/router.jsx

const rootRoute = [
  {
    path: '/',
    component: require('./routes/App'),
    indexRoute: { onEnter: (nextState, replace) => replace('/bt') },
    getChildRoutes(partialNextState, cb) {
      require.ensure([], (require) => {
        cb(null, [
          require('./routes/Bt'),
        ]);
      });
    },
  },
  {
    path: '/login',
    component: require('./routes/Login'),
  },
  {
    path: '*',
    component: require('./routes/Error'),
  },
];

src/routes/Bt/index.js

/* eslint no-shadow: ["error", { "allow": ["nextState", "cb", "partialNextState", "require"] }]*/
/* eslint-env es6*/

module.exports = {
  path: 'bt',
  getIndexRoute(nextState, cb) {
    require.ensure([], (require) => {
      cb(null, { component: require('./Dashboard') });
    });
  },
  getChildRoutes(partialNextState, cb) {
    require.ensure([], (require) => {
      cb(null, [
        {
          path: 'breakdown',
          component: require('./Breakdown/breakdown'),
          getIndexRoute(nextState, cb) {
            require.ensure([], (require) => {
              cb(null, { component: require('./Breakdown/blist') });
            });
          },
          getChildRoutes(partialNextState, cb) {
            require.ensure([], (require) => {
              cb(null, [
                {
                  path: 'list',
                  component: require('./Breakdown/blist'),
                },
                {
                  path: 'add',
                  component: require('./Breakdown/bedit'),
                },
                {
                  path: 'info/:id',
                  component: require('./Breakdown/binfo'),
                },
                {
                  path: 'edit/:id',
                  component: require('./Breakdown/bedit'),
                },
                {
                  path: 'alist',
                  component: require('./Breakdown/alist'),
                },
                {
                  path: 'ainfo/:id',
                  component: require('./Breakdown/ainfo'),
                },
              ]);
            });
          },
        },
        {
          path: 'dashboard',
          component: require('./Dashboard'),
        },
        {
          path: 'profile',
          component: require('./Profile'),
        },
      ]);
    });
  },
};

这种深层次的路由是可以解析到的.

不是很理解这句话

因此, 在路由结构里面的member(app), 写到了子路由外,脱离了tabbar的父组件的包含.

为什么要放在外面

深层次嵌套的依旧渲染不出来.

是否是因为 html 文件里引用的是 index.js,改成 /index.js 试试?昨天内网也有个同学遇到了这个问题。

改成/index.js就work了

Was this page helpful?
0 / 5 - 0 ratings