前言
通过路由,每个页面都有一个唯一的 URL。用户可以直接访问某个页面, 有了前进和后退的功能,更好的传递状态,url上能携带参数。
BrowserRouter和HashRouter比较
BrowserRouter
- 调用的是H5 history API,低版本兼容性问题。
- 路径:localhost:3000/demo/a
- 刷新后对路由state参数没有任何影响,因为state保存在history对象中。
HashRouter
- 使用的是URL哈希值
- 路径:localhost:3000/#/demo/a
- 刷新后会导致路由state参数的丢失!!!
全局绑定路由数组的形式
通过js定义createBrowserRouter
指定路由数组,然后通过Provider
提供绑定路由。即可实现完整的路由构建。
scss
// 接收数组
const globalRouters = createBrowserRouter([])
接收的数组中的对象常用的参数:
path
: 路径element
: 组件标签children
: 内部嵌套路由(对于组件上需要使用<Outlet></Outlet>
)
css
[ { path: '/home', element: <Home />, },]
最后在根目录下绑定全局的路由
ini
<RouterProvider router={globalRouters}>
使用标签形式构建路由
一层一层的通过Route来制定每一层的路由路径和对应的组件内容。如果嵌套路由,需要route再往下一级再指定。
xml
<BrowserRouter>
<Routes>
<Route path='/' element={<Login />} />
<Route path='home' element={<App />}>
<Route path='page1' element={<Page1 />} />
<Route path='page2' element={<Page2 />} />
<Route path='page3' element={<Page3 />} />
</Route>
</Routes>
</BrowserRouter>
路由插槽 Outlet
注意在使用嵌套路由的时候,父路由有提供占位的地方,由子路由匹配到的组件填补上去。
如下App组件内部有标签<Outlet/>
来提供占位。
javascript
function App(props) {
return (
<div>
<h1>标题1</h1>
<Outlet />
</div>);
}
export default App;
此时如果父路由完全匹配,则会呈现子索引路由;如果没有索引路由,则不会呈现任何内容
xml
<Route path="/" element={<App />}>
<Route path="messages" element={<DashboardMessages />}/>
<Route path="tasks" element={<DashboardTasks />} />
</Route>
兜底路由
可以通过route指定*来实现最后兜底能指定的路由组件,表明最后一定有匹配到的组件内容
ini
<Route path="*" element={<View />}>
实现路由跳转
js实现跳转
可以通过hook,使用useNavigate
来实现路由的跳转
scss
const navigate = useNavigate()
navigate('/home')
注意: useNavigate
需要使用在Router
标签的包裹下,可以将HashRouter
或者是 BrowserRouter
包裹在全局下,这样就能函数下都能使用了。也要保证在函数组件中哦。
通过标签实现跳转
<Link>
是一个基础的导航组件,用于在应用内创建超链接<NavLink>
是<Link>
的增强版,专门用于导航链接。它会在当前 URL 匹配to
属性时自动添加一个active
类名(默认为active
),从而便于高亮显示当前选中的导航项
ini
<Link to="/page/page1">跳转</Link>
<NavLink to="/page/page1">跳转Page1</NavLink>
注意使用Link
的时候,也要需要使用在Router
标签的包裹下,可以将HashRouter
或者是 BrowserRouter
路由参数
v6版本search形式获取值
react-router-dom
v6版本新增 useSearchParams
,比较推荐使用
scss
// 上传参数
navigate("/page1?name=Eula&age=18");
// 获取参数
let [searchParams, setSearchParams] = useSearchParams()
console.log(searchParams.get('name')) // "Eula"
console.log(searchParams.get('age')) // 18
通过params路径占位传参数
一般用于在地址路径上占位参数,例如 "/page1/:name/:age
"
第一种通过路由配置表配置参数占位(配置)
css
{
path: "/",
element: withLoadingComponents(<Home />),
children: [
{
path: "/page1/:name/:age",//注意这里 可以占位多个
element: withLoadingComponents(<Page1 />)
},
]
},
第二种通过js跳转路由时传入参数
scss
navigate("/page1/Eula/18");
此时都可以通过useParams
方法来获取参数,会封装成对象。
vbscript
// 使用useParams 函数
const params = useParams()
console.log("params:",params);// 打印 { "name": "Eula", "age": "18"}
通过state传对象
使用state传参时,参数需要放到state对象里面;
注意:此时路由上不能有params 传参
时的参数占位,否则无法跳转;
javascript
// 传参
navigate("/page1",{ state: {name:'Eula',age:"18"}});
<Link to="new-path" state={{ some: "value" }} />
// 获取参数
// 获取navigate中传递的state中的信息
let location = useLocation();
console.log("params:",location);
location
对应的对象的参数
hash
: 当前 URL 的哈希值key
: 该位置的唯一密钥pathname
: 页面路径search
: 当前 URL 的查询字符串state
: 针对传入的参数对象