本文使用的 react-router 版本爲 2.8.1react
React Router本身就有一套按需加載解決方案,將代碼拆分紅多個小包,在瀏覽過程當中實現按需加載;webpack
如過你的項目搭配了webpack打包工具,那麼須要在webpack.config.js
的output
內加上chunkFilename
web
output: {
path: path.join(__dirname, '/../dist/assets'),
filename: 'app.js',
publicPath: defaultSettings.publicPath,
// 添加 chunkFilename
chunkFilename: '[name].[chunkhash:5].chunk.js',
},
複製代碼
name是代碼裏建立chunk指定的名字,若是代碼中沒有指定,則webpack會默認分配id號碼做爲name; chunkhash是文件的hash碼,由於hash碼比較長,因此這裏只取前五位。bash
咱們須要讓路由動態加載組件,須要將 component
換成 getComponent
。首先將路由拆出來,建立一個根路由 rootRoute:react-router
const rootRoute = {
path: '/',
indexRoute: {
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('components/layer/HomePage'))
}, 'HomePage')
},
},
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('components/Main'))
}, 'Main')
},
childRoutes: [
require('./routes/baidu'),
require('./routes/404'),
require('./routes/redirect')
]
}
ReactDOM.render(
(
<Router
history={browserHistory}
routes={rootRoute}
/>
), document.getElementById('root')
);
複製代碼
這裏有四個屬性:app
path 不用多說,匹配路由;異步
getComponent 對應於之前的 component 屬性,可是這個方法是異步的,也就是當路由匹配時,纔會調用這個方法。函數
這裏面有個 require.ensure 方法工具
require.ensure(dependencies, callback, chunkName)
複製代碼
這是 webpack 提供的方法,這也是按需加載的核心方法。第一個參數是依賴,第二個是回調函數,第三個就是上面提到的 chunkName,用來指定這個 chunk file 的 name。ui
indexRoute 用來設置主頁。(單獨抽離主頁) 注意這裏的 indexRoute 寫法, 這是個對象,在對象裏面使用 getComponent。
childRoutes 子路由 這裏面放置的就是子路由的配置,對應於之前的子路由們。咱們將之前的 /baidu、/404 和 * 都拆了出來,接下來將分別爲他們建立路由配置。
路由控制 上面的childRoutes 裏面,咱們 require 了三個子路由,在目錄下建立 routes 目錄,將這三個路由放置進去。
routes/
├── 404
│ └── index.js
├── baidu
│ ├── index.js
│ └── routes
│ ├── frequency
│ │ └── index.js
│ └── result
│ └── index.js
└── redirect
└── index.js
複製代碼
和 rootRoute 相似,裏面的每一個 index.js 都是一個路由對象: /404/index.js
module.exports = {
path: '404',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('components/layer/NotFoundPage'))
}, 'NotFoundPage')
}
}
複製代碼
/baidu/index.js
module.exports = {
path: 'baidu',
getChildRoutes(partialNextState, cb) {
require.ensure([], (require) => {
cb(null, [
require('./routes/result'),
require('./routes/frequency')
])
})
},
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('components/layer/BaiduPage'))
}, 'BaiduPage')
}
}
複製代碼
/baidu/routes/frequency/index.js
module.exports = {
path: 'frequency',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('components/layer/BaiduFrequencyPage'))
}, 'BaiduFrequencyPage')
}
}
複製代碼
等················
下面來講一下設置Redirect
咱們須要把這個重定向的路由單獨拆出來,也就是 *
這個路由,咱們上面已經爲他建立了一個 redirect 目錄。這裏使用到 onEnter
方法,而後在這個方法裏改變路由狀態,調到另外的路由,實現 redirect :
/redirect/index.js官方例子
module.exports = {
path: '*',
onEnter: (_, replaceState) => replaceState(null, "/404")
}
複製代碼