1.前言
路由 是中大型项目不可或缺的
先做一些准备工作2个界面组件 ,便于路由跳转
熟悉一下路由基础
2. 城市组件
/src/pages/cities/index.js
写标签的 需要先写出 左半边<然后敲完标签 会自动生成 另外一半
import React, { Component } from 'react'
export default class index extends Component {
render() {
return (
<div>
<h1>城市列表</h1>
</div>
)
}
}
3. 搜索界面
/src/pages/citySearch/index.js
import React, { Component } from 'react'
export default class index extends Component {
render() {
return (
<div>
<h1> 城市搜索</h1>
</div>
)
}
}
4. 路由依赖安装
npm i react-router-dom -S
5. 路由引用
App.js 全局使用
import RouterComponent from "./pages/router"
function App() {
return (
<div className="App">
<RouterComponent></RouterComponent>
</div>
);
}
export default App;
6. 路由配置
参考
vue的配置
pages/router/index.js
1.png
Router作为BrowserRouter的别名 从react-router-dom引入
BrowserRouter是对路由配置的容器不能省
7. 匹配 ---path
7.1 path属性设置
Route我习惯写成 单标签闭合标签<然后敲完标签后,再敲个/就不会 生成 另外的结束标签了
<Router>
<Route path="/" component={CityComponent} />
<Route path="/search" component={CitySearchComponet} />
</Router>
问题效果
1.gif
/根路径默认匹配所有,所以/search会匹配2个,显示2个
/search/a和/search/assss/sfaf都能匹配上, 因为默认是模糊匹配
7.2 精确匹配 exact
exact 设置
return (
<div>
<Router>
<Route exact path="/" component={CityComponent} />
<Route exact path="/search" component={CitySearchComponet} />
</Router>
</div>
)
精确匹配 只有
/才能匹配
只有一级/search才能匹配 后面再加 2级,3级都匹配不上了
8.404组件
pages/404/index.js
Link来源于路由依赖 类似Vue的router-link,写法以一样,只是标签名不一样而已,to的值是想要跳转的,路由的,对应的path值
import React, { Component } from 'react';
import {
Link } from "react-router-dom"
export default class Component404 extends Component {
render() {
return (
<div>
<h1> 404 <Link to="/"> 首页 </link> </h1>
</div>
)
}
}
9. 404路由配置
因为404 是都匹配不到 才走404 的,所以放到路由配置的末尾
不需要写path属性
return (
<div>
<Router>
<Route exact path="/" component={CityComponent} />
<Route exact path="/search" component={CitySearchComponet} />
<Route component={Component404 }/>
</Router>
</div>
)
问题
2.gif
10. switch 解决问题
因为 404组件没写path 所以都能匹配上,
但我们是想要所有的路由 只匹配一个就行了, 所以需要引入一个
Switch组件
10.1 引入
import {
BrowserRouter as Router,
Route,
Switch,
Redirect,
withRouter,
Link,
NavLink
} from "react-router-dom";
10.2 使用Switch
Switch注意大写 包裹着 所有的路由
return (
<div>
<Router>
<Switch>
<Route exact path="/" component={CityComponent} />
<Route exact path="/search" component={CitySearchComponet} />
<Route component={Component404 }/>
</Switch>
</Router>
</div>
)
效果就不在贴图了,要不然图片太多了
11. 重定向 Redirect
Redirect来源于 路由依赖具名导入
<Redirect from="/home" to ="/" />
from从哪个路由 跳转 ,也就是哪个路由需要重定向
上面的 地址栏 输入/home会重定向到/
12.withRouter
非页面组件想拥有
router功能
withRouter来源于 路由依赖的具名导入
12.1 核心代码
class Swiper extends Component {
render() {
console.log("轮播图", this.props)
return (
<div>
<button onClick={() => { this.props.history.goBack() }}>返回</button>
<h1>轮播图</h1>
</div>
)
}
}
// 将路由注入 Swiper
Swiper = withRouter(Swiper)
12.2编程式导航
类似vue里面的导航
1.png
history里面 JS的相关API都有,所以可以自由操作
13. 非页面组件路由配置
像路由一样使用就行
<Route component={Swiper }/>
14.嵌套路由
嵌套路由 顶层路由不要加 exact
{/* 嵌套路由 顶层路由不要加 exact!!!!*/}
<Router>
<Switch>
<Route exact path="/" component={CityComponent} />
<Route exact path="/search" component={CitySearchComponet} />
<Route path="/home" render={() => {
return (
<HomeComponent>
<Route exact path="/home/wx" component={WxComponent} />
<Route exact path="/home/my" component={MyComponent} />
<Route exact path="/home/fd" component={FdComponent} />
<Route exact path="/home/ad" component={AdComponent} />
</HomeComponent>
)
}}>
</Route>
<Route component={Component404 }/>
</Switch>
</Router>
15. 嵌套路由出口
子路由是在
HomeComponent里面所以出口也在HomeComponent里面
出口直接是{this.props.children}占位 和vue <router-view />类似
class HomeComponent extends Component {
render() {
return (
<div>
{/* vue里面这样写 <router-view /> */}
{/* 占位标志 */}
{this.props.children}
<div className={styles.tabBar}>
<ul>
<li>
<NavLink to="/home/wx" activeClassName={styles.selected}>
<i className="myFont"></i>
<p>微信</p>
</NavLink>
</li>
<li>
< NavLink to = "/home/my"
activeClassName = {
styles.selected
} >
<i className="myFont"></i>
<p>我的</p>
</NavLink>
</li>
<li>
<NavLink to="/home/fd" activeClassName={styles.selected}>
<i className="myFont"></i>
<p>朋友圈</p>
</NavLink>
</li>
<li>
<NavLink to="/home/ad" activeClassName={styles.selected}>
<i className="myFont"></i>
<p>通讯录</p>
</NavLink>
</li>
</ul>
</div>
</div>
);
}
}
16. iconfont
这里引用了 阿里妈妈的图标库,我是使用在线的
1.png
完全可以自己在
assets/下面放 图标相关的文件




