本篇内容:
- 单一的路由无嵌套
- 多层嵌套路由
- 获取路径中的参数
- 按需加载
单一的路由无嵌套
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,description:"说",subs:[ { path:‘/speak/‘,component:CN,description:"说-汉语" },{ path:‘/speak/english‘,component:English,description:"说-英语" },{ path:‘/read‘,component:Read,description:"读",subs:[ { path:‘/read/‘,component:ReadBook,description:"读-课文" },{ path:‘/read/newspaper‘,component:ReadNews,description:"读-报纸" },{ path:‘/writ‘,component:Writ,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‘),delay:3000})
打包文件情况对比:
首屏加载情况对比:
参考文档:
https://reacttraining.com/react-router/web/example/route-config
https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/guides/code-splitting.md
https://github.com/jamiebuilds/react-loadable
可参考其他文章:https://www.cnblogs.com/alan2kat/p/7754846.html