react-router知识点

134 阅读5分钟

后续补充中…………

React-router

路由:根据不同的url规则,给用户展示不同的视图(页面)

当一个项目变复杂的时候,我们就需要分模块处理和展示,以前处理的方式是分成多个页面,用url跳转链接,但这样会刷新整个页面,重新请求资源,并且js状态都会丢失

从vue和react开始,就有了单页面应用SPA,整个应用只加载一个页面,后续与用户交互的过程中,通过dom操作在这个单页上动态生成结构和内容

使用SPA的优点是:减少从服务端的请求资源,页面切换快

缺点:

首次进入页面比较慢

不利于SEO

路由原理:

前端的单页面修改地址栏url的时候并不会真正的发送请求,而仅仅是修改url,然后通过地址修改监听方法去处理修改路由之后的具体操作(具体显示对应的页面)

例如:路由现在又两种模式

1、 基于url的hash模式

当地址栏url修改时会使用hasChange方法去监听地址栏的改变,然后再函数内使用JavaScript去处理显示页面逻辑

2、基于HTML5 History Api的路由

react-router-dom

在react中我们现在使用的是react-router-dom

 下载   npm i react-router-dom
 
 
 

使用

import {BrowserRouter} from "react-router-dom"

路由有两个模式

1、哈希模式:Hash

2、history模式

路由模式的设置

vue中路由模式是在配置中配置,但是react中的路由是一个组件,所以需要在组件中使用

在项目的入口文件中引入路由模式组件

// 这里使用的是history模式

import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

视图中如何使用

在组件中使用需要引入路由的Route组件

import { Route } from "react-router-dom";

function App() {
  return <div>
      <Route path="/" exact component={IndexPage} />
      <Route path="/about" exact strict component={AboutPage} />
      <Route path="/about/details" exact strict component={AboutDetailsPage} />
  </div>;
}

组件中的属性含义:

path:默认匹配的路径,当前url以path进行匹配(默认是模糊匹配)

exact:精确匹配:当url===path  以及url===path/ 的时候都可以进行匹配

strict:严格匹配:url===path 严格匹配必须基于精确匹配,要用strict时候必须要有exact

component :路径匹配成功之后要显示的视图

如果使用模糊匹配则在匹配路由,向下面的配置,则会出现indexPage和AboutPage同时渲染出现在视图上,当然这不是我们想要的,所以有精确匹配的属性exact

上面说的是路由显示视图的组件,那如果我们想跳转如何做呢。

如果想之前使用a标签跳转的话就会刷新整个页面,并且会发出新的请求去渲染页面。这样有违背我们使用单页面的初衷,要想做在跳转时候不刷新页面我们使用Link组件进行跳转

import { Link } from "react-router-dom";
// 应用内跳转使用 Link 组件,to 属性跳转地址
// 外链跳转还是使用 a 标签
function Nav() {
  return <nav>
      <Link to="/">首页</Link>
      <span> | </span>
      <Link to="/about">关于</Link>
      <span> | </span>
      <Link to="/about/details">关于-详情</Link>
      <span> | </span>
      <a href="https://www.baidu.com" target="_blank">百度</a>
  </nav>
}

export {Nav};

虽然link组件在浏览器会渲染成a标签,但如果要跳转外部网页在浏览器中渲染出来就会带前缀,导致不能跳转。所以在项目内要跳转外部地址时候还是需要使用a标签

组件内属性

to属性:要跳转的地址,和Route组件中的path对应


多路径匹配

1、Route中的多路径匹配:就是地址栏输入"/","/home","/index"都可以匹配到首页

这里要实现多路径匹配,path可以改为数组

<Route path={["/","/home","/index"]} exact component={IndexPage} />

重定向到错误页面,Redirect组件

如果地址栏输入的path没有匹配到路劲或者输入为空,则不会显示正确视图,我们可以给重定向到404页面 可以使用Redirect组件


// Redirect 重定向
// to 属性:将url重新定义的结果
// from 要进行重定向的utl,如果为空,则代表所有地址都进行重定向
import { Switch, Route, Redirect } from "react-router-dom";
import Nudefined from "./pages/Nndefined";

function App() {
  return <div>
      <Route path="/" exact component={IndexPage} />
      <Route path="/about" exact strict component={AboutPage} />
      <Route path="/about/details" exact strict component={AboutDetailsPage} />
      
      // 如果上面都没有匹配到则会重定向到404页面
      <Route path="/404" component={Nudefined} />
	  <Redirect to="/404"> </Redirect>
  </div>;
}

switch组件

使用方法

import { Switch, Route, Redirect } from "react-router-dom";
import Nudefined from "./pages/Nndefined";

function App() {
  return <div>
  	<switch>
      <Route path="/" exact component={IndexPage} />
      <Route path="/about" exact strict component={AboutPage} />
      <Route path="/about/details" exact strict component={AboutDetailsPage} />
      
      // 如果上面都没有匹配到则会重定向到404页面
      <Route path="/404" component={Nudefined} />
	  <Redirect to="/404"> </Redirect>
    </switch>
  </div>;
}

使用switch组件的作用是:先匹配到那个路由就渲染哪个,就不会在匹配下面的组件,就像switch()case一样,在匹配到条件只有就break,不再向下寻找

组件给路由传值

render属性,接收一个函数,函数的返回值为要渲染的视图

<Route path='/about' render={()=>{
return <AboutPage user={{name:"tom"}}></AboutPage>}}
></Route>

可以通过组件属性props进行传值,在AboutPage组件中使用pops就可以获取到,这里还可以传路由的参数

NavLink

NavLink可以给选中的路由加样式


import { NavLink } from "react-router-dom";
/*
  NavLink 功能和 Link 一致,但多了当前选中项
  1. 使用 NavLink 组件时,NavLink 会根据当前 URL 以及 自身的 to 属性,去做匹配,匹配成功则给当前项加上选中的 class
    匹配规则:
      1. 默认是模糊匹配
      2. 可以加 精确匹配
  - activeClassName: 匹配成功之后,要添加的class名,默认为 active
  - activeStyle:匹配成功之后,要显示的style
  - isActive() 判断当前是否应该选中, 返回值 true 选中,false 不选中
*/
function Nav(props) {
  return (
    <div className="nav">
      <NavLink
        to="/"
        activeClassName="active"
        isActive={(match, location) => {
          const { pathname } = location;
          return pathname == "/" || pathname.includes("/home");
        }}
      >
        全部
      </NavLink>
      <NavLink to="/good" activeClassName="active">
        精华
      </NavLink>
      <NavLink to="/share" activeClassName="active">
        分享
      </NavLink>
      <NavLink to="/ask" activeClassName="active">
        问答
      </NavLink>
    </div>
  );
}

export default Nav;

动态路由以及hook之后补充