网站功能建设,湛江建设网官方网站,湖北省建设厅网站如何申诉,墨西哥网站后缀文章目录React-RouterURL的hashHTML5的HistoryRouter的基本使用路由映射配置路由的嵌套路由配置和跳转Link和NavLink#xff1a;手动路由的跳转路由参数传递Navigate导航Not Found页面配置路由的配置文件React-Router
前端路由是如何做到URL和内容进行映射呢#xff1f;怎么…
文章目录React-RouterURL的hashHTML5的HistoryRouter的基本使用路由映射配置路由的嵌套路由配置和跳转Link和NavLink手动路由的跳转路由参数传递Navigate导航Not Found页面配置路由的配置文件React-Router
前端路由是如何做到URL和内容进行映射呢怎么原生的监听URL的改变。
URL的hash
URL的hash也就是锚点(#), 本质上是改变window.location的href属性 我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新 hash的优势就是兼容性更好在老版IE中都可以运行但是缺陷是有一个#显得不像一个真实的路径。 hashchange事件触发时事件对象会有hash改变前的URLoldURL和hash改变后的URLnewURL两个属性
window.addEventListener(hashchange,function(e) { console.log(e.oldURL); console.log(e.newURL) },false);
HTML5的History
◼ history接口是HTML5新增的, 它有六种模式改变URL而不刷新页面 replaceState替换原来的路径 pushState使用新的路径 popState路径的回退 go向前或向后改变路径 forward向前改变路径 back向后改变路径 popstate 事件是通过 window.addEventListener(popstate) 进行注册的。但触发条件需要满足下面两点
点击浏览器的【前进】【后退】按钮或者调用 history 对象的 back、forward、go 方法 之前调用过 history 对象的 replaceState 或 pushState 方法
Router的基本使用
◼ 安装React Router
npm install react-router-do◼ react-router最主要的API是给我们提供的一些组件
◼ BrowserRouter或HashRouter
Router中包含了对路径改变的监听并且会将相应的路径传递给子组件
BrowserRouter使用history模式
HashRouter使用hash模式
-src
—index.js
import React from react;
import ReactDOM from react-dom/client;
import App from ./App;
import { Provider } from react-redux;
import store from ./store;
import { HashRouter,BrowserRouter } from react-router-dom;const root ReactDOM.createRoot(document.getElementById(root));
root.render(// React.StrictModeHashRouterProvider store{store}App //Provider/HashRouter// /React.StrictMode
);
路由映射配置
◼ Routes包裹所有的Route在其中匹配一个路由
Router5.x使用的是Switch组件
◼ RouteRoute用于路径的匹配
path属性用于设置匹配到的路径
element属性设置匹配到路径后渲染的组件
✓ Router5.x使用的是component属性
exact精准匹配只有精准匹配到完全一致的路径才会渲染对应的组件
✓ Router6.x不再支持该属性
-src
—App.jsx
import {Routes,Route
} from react-router-dom;export class App extends PureComponent {render() {RoutesRoute path/home element{Home /}/Routes}}路由的嵌套
◼ 在开发中路由之间是存在嵌套关系的。
◼ 组件用于在父路由元素中作为子路由的占位元素。
-src
—pages
-------App.jsx RoutesRoute path/home element{Home /}Route path/home/homeChild element{HomeChild /}/Route/Route/Routes-src
—pages
-------Home.jsx
子路由的出口 组件用于在父路由元素中作为子路由的占位元素。
这样HomeChild组件就会被渲染到Home组件的占位元素的位置 export class Home extends PureComponent {render() {divh2Home Page/h2div{/* 占位组件 */}Outlet //div/div}}路由配置和跳转
Link和NavLink
通常路径的跳转是使用Link组件最终会被渲染成a元素
NavLink是在Link基础之上增加了一些样式属性默认叫active的className通过配置css可以让选中的标签展现active类名下的样式
to属性Link中最重要的属性用于设置跳转到的路径
-src
—App.jsx
import {Routes,Route
} from react-router-dom;
import ./style.cssexport class App extends PureComponent {render() {divnavLink to/home首页/LinkNavLink to/home首页/NavLink/navRoutesRoute path/home element{Home /}/Routes/div}}-src
—style.css
nav .active {color: red;font-size: 18px;
}手动路由的跳转
◼ 实际上我们也可以通过JavaScript代码进行跳转。
我们知道Navigate组件是可以进行路由的跳转的但是依然是组件的方式。
如果我们希望通过JavaScript代码逻辑进行跳转比如点击了一个button那么就需要获取到navigate对象。
◼ 在Router6.x版本之后代码类的API都迁移到了hooks的写法
如果我们希望进行代码跳转需要通过useNavigate的Hook获取到navigate对象进行操作
例子
import {useNavigate,
} from react-router-dom;export function RouterHook() {const navigate useNavigate()return(divbutton onClick{e navigate(/home)}去home/button/div)
} 那么如果是一个函数式组件我们可以直接调用但是如果是一个类组件呢
类组件我们可以使用一个高阶组件包裹在返回的组件的props中写入react-router-dom的方法,这里封装了useLocation, useNavigate, useParams, useSearchParams四个钩子
useParams和useSearchParams钩子用来接收路由传参
useLocation钩子监听路由的地址
useNavigate钩子实现手动路由跳转
案例
-src
—hoc
-------withRouter.js
import { useLocation, useNavigate, useParams, useSearchParams } from react-router-dom;function withRouter(WrapperComponent) {return function (props) {// 1.导航const navigate useNavigate()// 2.动态路由的参数: /detail/:idconst params useParams()// 3.查询字符串的参数: /user?namewhyage18const [searchParams] useSearchParams()const query Object.fromEntries(searchParams)// 4.路由地址const location useLocation()const router { navigate, params, location, query }return (WrapperComponent{...props}router{router}/WrapperComponent);};
}export default withRouter再到类组件中使用withRouter高阶组件包裹需要使用router hook的组件上
import withRouter from ../hoc/withRouter;export class Home extends PureComponent {....
}export default withRouter(Home);路由参数传递
◼ 传递参数有二种方式
动态路由的方式
search传递参数
◼ 动态路由的概念指的是路由中的路径并不会固定
比如/detail的path对应一个组件Detail
如果我们将path在Route匹配时写成/detail/:id那么 /detail/abc、/detail/123都可以匹配到该Route并且进行显示
这个匹配规则我们就称之为动态路由
通常情况下使用动态路由可以为路由传递参数。
路由传递参数
import {Link,Routes,Route,
} from react-router-dom;export function App(props) { return (divLink to/home/detail/123给detail页面传参123/LinkRoutesRoute path/home/detail/:id element{Detail /}/Route/Routes/div)
} 在组件中接收参数
import React, { PureComponent } from react
import { withRouter } from ../hocexport class Detail extends PureComponent {render() {const { router } this.propsconst { params } routerreturn (divh1Detail Page/h1h2id: {params.id}/h2/div)}
}export default withRouter(Detail)◼ search传递参数
给Contexta组件路由传参
import {Link,Routes,Route,
} from react-router-dom;export function App(props) { return (divLink to/home/context?age18name顽皮宝给contexta页面传参/LinkRoutesRoute path/home/context element{Contexta /}/Route/Routes/div)
} 在组件中接收参数
import React, { PureComponent } from react
import { withRouter } from ../hocexport class Contexta extends PureComponent {render() {const { router } this.propsconst { query } routerreturn (divh1User: {query.name}-{query.age}/h1/div)}
}export default withRouter(Contexta)Navigate导航
◼ Navigate用于路由的重定向当这个组件出现时就会执行跳转到对应的to路径中
j例子在匹配到’/的时候直接跳转到/home页面
Route path/ element{Navigate to/home /}/Route
Not Found页面配置
◼ 如果用户随意输入一个地址该地址无法匹配那么在路由匹配的位置将什么内容都不显示。
◼ 很多时候我们希望在这种情况下让用户看到一个Not Found的页面。
开发一个Not Found页面
配置对应的Route并且设置path为*即可 Route path* element{NotFound /}/Route
路由的配置文件
◼ 目前我们所有的路由定义都是直接使用Route组件并且添加属性来完成的。
◼ 但是这样的方式会让路由变得非常混乱我们希望将所有的路由配置放到一个地方进行集中管理
在早期的时候Router并且没有提供相关的API我们需要借助于react-router-config完成
在Router6.x中为我们提供了useRoutes API可以完成相关的配置
◼ 如果我们对某些组件进行了异步加载懒加载那么需要使用Suspense进行包裹
-src
—router
-------index.js
import Home from ../pages/Home
import HomeRecommend from ../pages/HomeRecommend// import About from ../pages/About
// import Login from ../pages/Login
import { Navigate } from react-router-dom
import React from react// 懒加载
const About React.lazy(() import(../pages/About))
const Login React.lazy(() import(../pages/Login))const routes [{path: /,element: Navigate to/home/},{path: /home,element: Home/,children: [{path: /home/recommend,element: HomeRecommend/},]},{path: /about,element: About/},{path: /login,element: Login/},
]export default routes
-src
—App.jsx
import React from react
import { Link, useRoutes } from react-router-dom
import routes from ./routerexport function App(props) {return (div classNameappdiv classNamenavLink to/home首页/LinkLink to/login登录/Link/divdiv classNamecontent{useRoutes(routes)}/div/div)
}export default App