本篇內容:
- 單一的路由無嵌套
- 多層嵌套路由
- 獲取路徑中的參數
- 按需加載
單一的路由無嵌套
routers.js
import Home from 'components/Home';
import News from 'components/News';
import User from 'components/User';
import My from 'components/My';
let routes=[
{
path:'/',
component:Home ,
exact:true
},
{
path:'/news',
component:News ,
},
{
path:'/user',
component:User
},
{
path:'/my',
component:My
},
]
export default routes;
App.jsx
import React, { Component } from 'react';
import { HashRouter as Router, Switch, Route } from "react-router-dom";
import routes from '../routers/index';
class App extends Component {
render() {
return (
<Router>
<div>
<Switch>
//主要邏輯在這里
{
routes.map((item, i) => {
if(item.exact){
return <Route exact path={item.path} component={item.component} key={i}/>
}else{
return <Route path={item.path} component={item.component} key={i}/>
}
})
}
</Switch>
</div>
</Router>
);
}
}
多層嵌套路由
let routes=[
{
path:'/hear',
component:Hear,
exact:true,
description:"聽",
subs:[
{
path:'/hear/',
component:HearIndex,
description:"聽-首頁"
},
{
path:'/hear/book',
component:HearBook,
description:"聽-課文"
},
]
},
{
path:'/speak',
component:Speak,
exact:true,
description:"說",
subs:[
{
path:'/speak/',
component:CN,
description:"說-漢語"
},
{
path:'/speak/english',
component:English,
description:"說-英語"
},
]
},
{
path:'/read',
component:Read,
exact:true,
description:"讀",
subs:[
{
path:'/read/',
component:ReadBook,
description:"讀-課文"
},
{
path:'/read/newspaper',
component:ReadNews,
description:"讀-報紙"
},
]
},
{
path:'/writ',
component:Writ,
exact:true,
description:"寫"
}
]
export default routes;
App.jsx
{
routes.map((item, i) => {
if (item.exact) {
//官方固定格式
return <Route exact path={item.path} key={i} render={ props => (<item.component {...props} routes={item.subs}/>) />
}
else {
return <Route path={item.path} key={i} render={ props => (<item.component {...props} routes={item.subs}/>)} />
}
})
}
//step 2,在對應的組件中再次遍歷
{
this.props.routes.map((item, i) => {
return <Route exact path={item.path}
component= {item.component}
key={i}/>
})
}
跳轉
this.props.history.push(`/about/type/${id}`)
this.props.history.replace(...)
注意:
不能在子組件中直接獲取,需要從父級傳入之后用props獲取;
跳轉時,如果還有事件未結束,則容易報錯!
如:
<LoginCom TIMEID={TIMEID} {...this.props}/>
獲取路徑參數
獲取對應的params
this.props.match.params.id
獲取?后面對應的值
const getQueryString = (str,name) => {
let result = str.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i"));
if (result == null || result.length < 1) {
return "";
}
return decodeURI(result[1], "utf-8");
}
如:http://localhost:3000/#/textbook/bishun?val=看
console.log(getQueryString(this.props.location.search,'val'));
按需加載
感覺這種方式最簡單:
基於 webpack, babel-plugin-syntax-dynamic-import, 和 react-loadable;
主要是利用了react-loadable這個高級組件,他是專門用來異步加載(也可以預加載)組件的。
cnpm i -S react-loadable @babel/plugin-syntax-dynamic-import
.babelrc
{
“ presets ”:[ “ @ babel / react ” ],
“ plugins ”:[ “ @ babel / plugin-syntax-dynamic-import ” ]
}
routers.js變化
import Loadable from 'react-loadable';
import DelayLoading from './DelayLoading';
const Home= Loadable({loader: () => import('../components/Home'), loading : DelayLoading,delay:3000})
const Login= Loadable({loader: () => import('../components/Login'), loading : DelayLoading,delay:3000})
打包文件情況對比:
首屏加載情況對比:
參考文檔:
https://reacttraining.com/react-router/web/example/route-config