前言:router文档直达:Home v6.18.0 | React Router
巴拉巴拉:本文档由vite+react搭配使用
创建vite项目
//在目标路径下cmd打开终端执行以下命令 //创建vite项目,根据指令进行操作 npm create vite@latest //切换路径到新创建的项目下 cd name //安装依赖 npm i //打开代码 code . //运行代码 npm run dev |
vite的项目目录
安装路由并使用
//安装react路由插件 npm install react-router-dom //在主页面页面最外层使用browserRouter包裹 main.tsx文件 import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App.tsx"; import "./index.css"; import { BrowserRouter } from "react-router-dom"; ReactDOM.createRoot(document.getElementById("root")!).render( <BrowserRouter> <React.StrictMode> <App /> </React.StrictMode> </BrowserRouter> ); //在app.tsx中使用useRoutes统一配置路由 App.tsx文件 //使用useRoutes统一配置路由 import { useRoutes } from "react-router-dom"; // 引入所需要路由的页面 //使用useRoutes统一配置路由 import { useRoutes } from "react-router-dom"; // 引入所需要路由的页面 //使用useRoutes统一配置路由 import { useRoutes } from "react-router-dom"; // 引入所需要路由的页面 import Tabbar from "./view/tabber"; import Home from "./view/home"; import Login from "./view/login"; export default function Index() { const element = useRoutes([ { path: "/*", element: <Tabbar />, children: [ { path: "Home", element: <Home />, }, ], }, { path: "Login", element: <Login />, }, ]); return element; } //使用navigate就可以进行简单的跳转 Tabber/index.tsx文件 //引入react-router-dom的 useNavigate 使用 navigate 进行跳转 import { useNavigate } from "react-router-dom"; const Tabber = () => { const navigate = useNavigate(); return ( <> <div>这是目录页</div> <button onClick={() => { navigate("/Login"); }} > 跳转到登录页 </button> <button onClick={() => { navigate("/Home"); }} > 跳转到主页 </button> </> ); }; export default Tabber; |
项目的目录结构
服务器路由browserRouter与前端路由hashRouter
browserRouter
如果前端使用了browserRouter
,每次改变路由时,会向服务器发送请求,因为服务器未配置对应的路径指向对应的文件,自然导致出现404的情况.(对于初始化页面,即路由为/时,不会发送请求
因此在使用browserHistory
需要再加一层服务器配置(node/nginx),让前端发送的请求映射到对应的html文件上.
hashRouter
由于hashRouter
会在路径上添加/#/
,而/#/
后面的所有都不会发送到服务器端,即对于服务器而言,路径依旧是localhost:3000
,路由切换在前端完成。
但是官方会更推荐使用browserRouter
,貌似是因为其构建于H5的History API
,比起hashRouter
,它多出了更多的方法操控url
前端路由实现方式
在单页面web网页中,单纯的浏览器地址改变,网页不会重载,如单纯的hash值改变,网页是不会变化的,因此我们的路由需要监听事件,并利用js实现动态改变网页。
- hash 模式:监听浏览器地址hash值变化,并执行相应的js切换。
使用window.location.hash 属性和window.onhashchange事件。可以监听浏览器hash值得变化,去执行相应的js切换网页。
hash路由实现原理:
- hash 指的是地址中 # 号以及后面的字符。称为散列值。
- 散列值不会随请求发送到服务器端的,所以改变hash,不会重新加载界面。
- 监听onhashchange事件,hash改变时,可以通过window.location.hash来获取和设置hash值。
- location.hash值的变化直接反应在浏览器的地址栏。
-
history 模式:利用H5 history API实现url地址改变,网页内容改变。window.history对象。它表示的是当前窗口的浏览历史,当发生改变时,只会改变路径,不会刷新界面。History对象就是一个堆栈。
方法 功能 History.back() 移动至上一个网站 History.forward() 移动至下一个网站 History.go() 接受一个参数,以当前网页为基准,正数向前跳转,负数返回,history.go(0)是刷新页面 History.pushState() 往history堆栈中添加一条记录。不会刷新界面,只会导致History对象变化,地址栏发生变化。 History.replaceState() 是替换当前history堆栈中最上层的记录。也是不会刷新界面,只会是Histoty对象变化,地址栏发生变化。
每当history对象发生变化,就会触发popstate事件:window.addEventListener("popstate",function(){}),只调用pushState或者replaceState是不会触发改事件的,只有调用back,forward,go才会触发该事件。
browserRouter与hashRouter的区别
... | BrowserRouter | HashRouter |
---|---|---|
底层原理 | 调用H5 history Api | 使用URL哈希值 |
地址栏 | localhost:3000/demo/a | localhost:3000/#/demo/a |
参数携带 | state刷新后不会消失 | 刷新后state参数会丢失 |
跳转:<Link></Link> 与 <NavLink></NavLink>
//to: string <Link to="/courses?sort=name" /> //to: object <Link to={{ pathname: '/courses', //链接地址的路径表示 search: '?sort=name', //?查询数值型的字符串 hash: '#the-hash', //#urlHash部分内容 state: { fromDashboard: true } //location想要在地址上持久化的属性 }} /> //to: function <Link to={location => ({ ...location, pathname: "/courses" })} /> <Link to={location => `${location.pathname}?sort=name`} /> //NavLink import { NavLink } from "react-router-dom"; <NavLink to="/messages" className={({ isActive, isPending }) => isPending ? "pending" : isActive ? "active" : "" } > Messages </NavLink>; |
//路由页面跳转 import { useNavigate } from 'react-router-dom' const navigate = useNavigate() <Typography.Link style={{ cursor: 'pointer' }} onClick={e => { e.stopPropagation() navigate(`/attack/detail?id=${record.id}`) }} > <span>详情</span> </Typography.Link> //跳转的页面接收参数 import { useLocation } from 'react-router-dom' const { search } = useLocation() |
window两个获取url对象的属性location和history
[JavaScript] location对象的属性与方法_location对象的属性或方法-优快云博客
对象 | 属性 | 说明 |
---|---|---|
location | host | 主机(域名) — blog.youkuaiyun.com |
port | 端口号 可选,省略时使用方案的默认端口(比如http的默认端口时80) | |
pathname | 路径 由零个或多个/隔开的字符串,一般表示主机上的一个目录或者文件地址---/qq_49900295/article/details/123550239 | |
search | 返回参数 | |
href | 整个url | |
hash | 返回#后边的内容 | |
方法 | ||
location.assign() | 重定向页面,作用等同于href | |
location.replace() | 替换当前页面,不能回退 | |
location.reload() | 重新加载页面 | |
history | ||
back() | 后退 | |
forward() | 前进 | |
go(参数) | 正数前进 负数后退 0刷新 |
react-router-dom hooks
hooks | 属性 | 说明 | 获取 |
---|---|---|---|
location | hash | 当前url的哈希值 | import { useLocation} from 'react-router-dom'; const location= useLocation(); location.pathname |
key | 该位置的唯一密钥 | ||
pathname | 该url路径 | ||
search | 当前url查询字符串 | ||
state | <Link state> 或 navigate 创建的位置的状态值。 | ||
useHistory | length | 当前历史记录中的条目数 | import { useHistory} from 'react-router-dom'; const history= useHistory(); history.push('ghsfdsfdfsdf,[{qwe:sdfds}]) |
action | 当前操作的类型,例如 PUSH、REPLACE 或 POP | ||
location | 当前位置的信息,包括 | ||
push(path,[state]) | 将新条目推入历史堆栈,并加载 | ||
replace(path,[dstate]) | 使用新path替换当前path | ||
go(n) | n为正数前进 n为负数后退 n为0刷新 | ||
useParams | import { useParams } from 'react-router-dom'; const params = useParams(); //获取一直的参数值 | ||
useSearchParams() | import { useSearchParams } from 'react-router-dom' const [searchParams, setSearchParams] = useSearchParams() //获取参数 // 执行完之后 url=/detail?user=郭芙蓉&skill=排山倒海 searchParams.get("id") 设置url参数 setSearchParams({ user:"郭芙蓉", skill:"排山倒海"}) //清空参数 setSearchParams({}) |