监听 URL 的变化,当 URL 变更时,它将使浏览器显示相应的页面
所以需要包裹在需要使用组件路由的最外层
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Routes, Link } from 'react-router-dom'
function App() {
return (
// 1.最外层必须使用BrowserRouter或者HashRouter包裹,
...
);
}
HashRouter
使用window.location.hash 属性和window.onhashchange事件
可以监听浏览器hash值得变化,去执行相应的js切换网页
hash路由实现原理:
hash 指的是地址中 #
号以及后面的字符,称为散列值
散列值不会随请求发送到服务器端的,所以改变hash,不会重新加载界面
监听onhashchange事件,hash改变时,可以通过window.location.hash来获取和设置hash值
location.hash值的变化直接反应在浏览器的地址栏
BrowserRouter
使用history首先应该了解window.history对象
它表示的是当前窗口的浏览历史,当发生改变时,只会改变路径,不会刷新界面
History对象就是一个堆栈
....
默认类名
点击之后,会显示高亮,高亮的默认类名是active
,我们只需要编写一个类名为active
的css样式即可
.active {
background-color:red;
}
特定类名
如果高亮的类名不是active,则需要使用
这种写法
function computedClassName({ isActive }) {
// setActives表示高亮的类名,也就是选中的样式,normal表示未选中的样式
// isActive为true则表示选中
return isActive ? 'setActives' : 'normal'
}
login组件
NavLink
跳转依靠的是to
属性
作用:只要
组件被渲染,就会修改路径,切换视图
replace表示跳转模式,默认是false,表示push,如果为true,表示replaceimport ReactDOM from 'react-dom';
import { BrowserRouter, Route, Routes, Navigate } from 'react-router-dom'
function App() {
return (
{/* 一开始进入页面路径是'/',我们重定向到/home页面 */}
} />
} />
);
}
function Home() {
return home组件
}
ReactDOM.render( , document.getElementById('root'))
} />
} />
组件必须被
组件包裹
内匹配到一个
之后,就不会继续向下匹配了
属性用于指定:匹配是否区分大小写(默认为false)
其实在实际开发中,我们如果总是用这种写法
进行开发
} /> 每次使用Route都要包裹一个Routes是比较麻烦的,因此就有了我们的路由表useRoutes()
我们使用路由表对路由进行统一管理
一般在src
文件夹下创建routes
文件夹,并在其中编写路由
语法:const element=useRoutes([{path:'路径',element:'组件',children:'子路由'}])
例子:
// 路由表
import About from '../page/About'
import Home from '../pages/Home'
export default [
{
path:'/about',
element:<About/>
},{
path:'/home',
element:<Home/>
}
]
import {useRoutes} from 'react-router-dom'
import routes from './routes'
// 路由表的使用
function App(){
const element = UseRoutes(routes)
return (
{element}
)
}
子路由不用写全路径
比如:
父路由:
/home
子路由:
/home/news
、/home/messages
path:'/home', element:<Home/>, children:[ { path:'new', element:<news/> },{ path:'messages', element:<messages/> } ]
import ReactDOM from 'react-dom';
import { BrowserRouter, Link, useRoutes, Navigate, Outlet } from 'react-router-dom'
function App() {
const element = useRoutes([
{
path: '/home', element: , children: [
{
path: 'news',
element:
}
]
},
{ path: '/', element: },
])
// 在路由区直接使用{element},不需要写` `
return { element }
}
function Home() {
return home组件
跳转到new组件
{/* 因为是home的子组件,所以在这里使用组件, */}
}
function News() {
return news组件
}
ReactDOM.render( , document.getElementById('root'))
路由添加占位符
path:'detail/:id/:title/:content'
跳转传递参数
接收参数
import {useParams} from 'react-router-dom'
function Detail(){
const {id,title,content} = useParams()
return (
- {id}
- {title}
- {content}
)
}
路由跳转传递参数
接收参数
import {useSearchParams} from 'react-router-dom'
function Detail(){
const [search,setSearch] = useSearchParams()
// 获取参数
const id = search.get('id')
const title = search.get('title')
}
setSearch
用于修改传递的参数,使用得较少
传递参数
接收参数
import {useLocation} from 'react-router-dom'
const {state:{id,title,content}} = useLocation()
const navigate = useNavigate();
navigate('/跳转路径',{replace:跳转模式(push或者replace,默认是push),state:{参数}})
navigate(-1)
:后退一步,navigate(1)
:前进一步
import ReactDOM from 'react-dom';
import { BrowserRouter, useRoutes, Navigate,useNavigate } from 'react-router-dom'
function App() {
const element = useRoutes([
{ path: '/home', element: },
{ path: '/news', element: },
{ path: '/', element: },
])
return {element}
}
function Home() {
const navigate=useNavigate()
function handleClick(){
navigate('/news')
}
return
}
function News() {
return news组件
}
ReactDOM.render( , document.getElementById('root'))