react-router可以解决路由问题,只需要添加[基于react-router4.x
]
yarn add react-router-dom
然后在index.js
中引入它,使用:
import {Link,BrowserRouter,Switch, Route} from 'react-router-dom';
ReactDOM.render((
<BrowserRouter>
<Switch>
<Route path="/list" component={ListDemo}/>
<Route path="/a" component={A}/>
<Route path="/b" component={B}/>
Switch>
BrowserRouter>
),mountdom)
这样就完成了路由的设置,而超链接则可以使用提供的Link
组件
<Link to="/a">a</Link>
等价于直接写a
。
在每个menu中传一个url属性,然后url代表那个地方被高亮,每个路由都重新创建一个menu即如下:
<BrowserRouter>
<Switch>
<Route exact path="/" render={props=><Menu {...props} url="list"><ListDemo/>SiderDemo>}/>
<Route path="/list" render={props=><Menu {...props} url="list"><ListDemo/>SiderDemo>}/>
<Route path="/a" render={props=><Menu {...props} url="a"><A/>SiderDemo>}/>
<Route path="/b" render={props=><Menu {...props} url="b"><B/>SiderDemo>}/>
Switch>
BrowserRouter>
但是每个页面的初次加载都会闪一下,重新加载了js。要想不闪则需要路由嵌套:
//上来路由只匹配到Menu中
<BrowserRouter>
<Switch>
<Route path="/" component={Menu}/>
Switch>
BrowserRouter>
//上面的route就一个组件menu,在menu中再次定义route,可以实现路由嵌套
<Menu>
<顶部>顶部>
<侧栏 selectedurl={this.props.location.pathname}>
侧栏>
<内容部分>
<Route exact path="/list" component={List}/>
<Route exact path="/a" component={At}/>
<Route exact path="/b" component={Bt}/>
内容部分>
<Menu>
这里主要是利用了每个页面都有的一个属性即props.location.pathname
是路由属性
1 多入口文件的形式,但是不易于按需加载,只能是实现了分开输出,没啥用。一般写的都是单入口应用。
2 异步import,或者require.ensure,然后在webpack中配置
output:{
filename:"[name]-bundle.js",
chunkFilename: "[name]-chunk.js",
path: __dirname+'/dist'
},
这样就生成一个bundle文件,多个chunk文件,name就是import的文件的名字,注意这里的注释是有用的直接决定了chunk输出的时候的[name]。
import(/* webpackChunkName: "app" */'./app').then(function(res){
let xx= res.default;//xx就是app的export default
})
create-react-app
创建的应用执行npm run eject
进行弹射。webpack中已经有了上面3中的配置,是可以直接生成多个chunk文件的。import React, { Component } from "react";
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null
};
}
async componentDidMount() {
const { default: component } = await importComponent();
this.setState({
component: component
});
}
render() {
const C = this.state.component;
return C ? this.props} /> : null;
}
}
return AsyncComponent;
}
const List=asyncComponent(()=>import(/* webpackChunkName: "list" */"./router/List"))
const At=asyncComponent(()=>import(/* webpackChunkName: "a" */"./router/A"))
const Bt=asyncComponent(()=>import(/* webpackChunkName: "b" */"./router/B"))
<HashRouter>
<Switch>
<Route path="/" component={SiderDemo}/>
Switch>
HashRouter>
class SiderDemo extends React.Component {
render() {
let selected=this.props.location.pathname.substring(1)
if(selected==="")selected="list"
return (
<Layout>
<Sider>
<Menu defaultSelectedKeys={[selected]}>
.........................
Menu>
Sider>
<Layout>
<Header>Header>
<Content >
<div>
<Route exact path="/list" component={List}/>
<Route exact path="/a" component={At}/>
<Route exact path="/b" component={Bt}/>
<Route exact path="/" component={List}/>
div>
Content>
<Footer>Footer>
Layout>
Layout>
);
}
}