React学习笔记(2)Router

497 阅读5分钟

React路由问题

HashRouter模式

  • 锚点的链接

BrowserRouter模式

  • h5的新特性主要是使用了 history.push() 这个方法,需要后台做特殊处理:比如重定向处理、404bug

Link 与 NavLink

  • Link 类似 htmla 标签
    • 渲染后也就是一个 a 标签。但是在写的时候尽量还是选择Link,因为Link内部做了一些特殊的处理,可以实现很多操作。它的 to、query、hash属性会被组合在一起并渲染为 href 属性。
// 路径跳转
<Link to="myPath">这是一个跳转</Link>
<Link to="myPath"/>

//对象参数跳转
<Link 
	to={{
    	pathname:'my_path',
        search:'?sort=123',
        hash:'#the-hash',
        state:{ fromDashboard:true }
    }}
/>
  • NavLinkLink 的差别在于,它有内置方法,只要点击,就会触发添加上类名,其它是没差别的。主要是用于做高冷
//activeClassName自定义添加的类名
<NavLink exact activeClassName="myName" to="myPath" /> 

// 直接增加一个样式
<NavLink 
	activeStyle={{
    	fontWeight:"blod",
        color:"red"
    }}
/>

匹配规则

  • route 路由是有三个属性来决定是否“匹配”一个URL的,分别是嵌套、路径语法、优先级
    • 嵌套关系React Router 使用路由嵌套的概念来让你定义 view 的嵌套集合,当一个给定的 URL 被调用时,整个集合中(命中的部分)都会被渲染。嵌套路由被描述成一种树形结构。React Router 会深度优先遍历整个路由配置来寻找一个与给定的 URL 相匹配的路由
// 访问路径 http://localhost:8088/#/login/my
<Route path="/Login" component={ Login } />
<Route path="/Login/my" component={ My } /> 
## 俩个都会被渲染出来,因为路径中有涉及到 /Login 匹配相同第一个就被渲染出来,第二个匹配后也相同也会被渲染出来
  • 此时加上exact 匹配规则就可以精准的匹配路径,添加了 exact 路径匹配不相同的是不会被渲染出来的,除非是遇到了 : * 特殊定义的符号,否则都会视为路径
// 访问路径 http://localhost:8088/#/login/my
<Route exact path="/Login/my" component={ My } /> 
<Route exact path="/Login" component={ Login } /> ## 非吾族类,这个不显示
<Route exact path="/Login/my" component={ My } />
## 并且这俩个( path="/Login/my" )都会显示出来,如果像只显示一个可以加上 switch组件,下面有介绍

因为路由路径中添加了 " :id? " 所以会把它认为是 " : " 前面是路径 " : " 后面是参数

URL参数

  • Route传递的时候是可以带上参数的

大部分路由路径是可以直接看字面理解的,但是遇到 : ? * 特殊符号则不一样,他们都是做过特殊处理的

## 请求路径前加上 " : " 就是一个请求参数
## 在请求参数后面加上 " ? " 号,代表加不加参数都可以,如果没有加上 " ? " 号且没有带上参数,则不会匹配渲染出来
<Route exact path="/demo/:id?/:name?" component={ My } /> 
http://localhost:8088/#/demo/1000/123

## 如果是 * 则代表匹配任意字符,直到匹配到,即使中文乱七八糟输入都没事,会把它当成字符串获取。如果没有符合的则会出现问题,不渲染出来
http://localhost:8088/login/img.23.是的。11-png-png/123

  • URL中也是可以获取 query string 类型的参数的

Switch

使用 Switch 组件 每次只会加载一个组件,只要获取到就不再往下找了

<Switch>
    <Route path="/Login" component={ My } /> ## 渲染它
    <Route path="/Login" component={ Login } />
</Switch>
  • 由于 Switch 组件只会加载一个组件,可以利用来处理跳转404页面功能
<Switch>
    <Route path="/Login" component={ My } /> ## 渲染它
    <Route path="/my" component={ Login } />
    <Route component={ NotFound } />
    ## 当所有配匹配不正确时,就会跳转至404页面中
</Switch>

strict

  • exact 匹配规则虽然可以阻止一些路径的重复,但是如果在路径后边加上了 / 就并不精准了,此时需要加上 strictstrictexact 需要在一起使用的
<Route exact path="/" component={ Home }></Route>
<Route path="/mine" component={ Mine }></Route>
<Route strict path="/mine/ucenter" component={ Mine }></Route>

Route的render

  • 可以使用 render 引入组件,并这样是以函数形式引入组件,可以传递数据。
  • 并且可以用来传递参数,传递的参数是不会在url上有显示的
<Route path="/demo" render={ ()=>{ return <My myData="这是隐私数据"/> } } />
/*My/My.jsx*/
const My = ({myData}) => {
    return (
        <>
            <div>{myData}</div>
        </>
    )
}

路由重定向

在实际开发中,很多页面是有权限需求的。这样就需要用户登录,当用户登录后,把后台返回的token或者其他验证,存放在缓存中。每次进入权限需求的页面,就验证缓存中是否有token。没有的话将页面重定向到登录页面中,让用户登陆。

  • 使用 Redirect 进入页面判断的形式,是否重定向
import { Redirect } from "react-router-dom";

<>
    {
        isLogin?
        <div>
            <div>已经登录了</div>
        </div>
        :<Redirect to="/login"/>
    }
</>
  • history.push()这个函数是进行添加的方式进行页面跳转,上一次的页面还是存在的。
  • 需要是被路由管理的组件,路由渲染后才会给组件添加上路由对象,如果是组件引入则需要我们自己传值进去。
  • 只有被路由管理的组件才有路由对象

官方也提供了一个解决方案,即使不是被路由管理的也可以拥有当前路由对象 ,使用高级组件withRouter

## 这个组件必须写在Router组件里面
//app.js
<Router>
    <Home></Home>
</Router>

//home.jsx
class Home extends Component {
	my code...
}
export default withRouter(Home);
//在导出的时候把到处的对象包裹起来

路由管理的组件

组件引入的

export default Home = () => {
  handleLogin=()=>{
      this.props.history.push("/login")
  }
  return (
  	<button onClick={ this.handleLogin }>点击去登录</button>
  )
}

  • 还有一种是replace这个是替换的方式,把上一次的页面给替换了。返回是返回不回去了
export default Home = () => {
  handleLogin=()=>{
      this.props.history.replace("/login")
  }
  return (
  	<button onClick={ this.handleLogin }>点击去登录</button>
  )
}

Prompt

  • 该组件主要作用是,在用户准备离开该页面时, 弹出提示, 返回true或者false, 如果为true, 则离开页面, 如果为false, 则停留在该页面
  • 这个组件可以检测input的框中是否有内容,如果有,路由跳转的时候就会有提示
<Prompt
    when={ !!this.state.name }
    message={"是否要离开"}
/>

路由嵌套

  • 路由嵌套,相当于子元素概念,父级嵌套子级,由路由控制渲染哪个
//app.js
<UserList>
  <Switch>
    <Route  path="/UserList/Member" component={ Member } />
    <Route  path="/UserList/Ordinary" component={ Ordinary } />
  </Switch>
</UserList>
//userList.jsx
class UserList extends Component {
    render() {
        return (
            <div>
                <h1>用户列表</h1>
                {
                    this.props.children
                }
            </div>
        );
    }
}