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> )
问题
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
类似
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
这里引用了 阿里妈妈的图标库,我是使用在线的
完全可以自己在
assets/
下面放 图标相关的文件