后续补充中…………
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之后补充