目录框架:
两种配置路由的方式,一种是组件式的,另一种是useRoutes
组件式的:
import React from 'react'
import { Route, Routes } from 'react-router-dom'
// import Film from '../views/Film/index.js'
// import Center from '../views/Center/index.js'
// import Cinema from '../views/Cinema/index.js'
import Redirect from './Redirect.js'
// import Detail from '../views/Detail/index'
// import NotFound from '../views/NotFound.js'
// import Nowplaying from '../views/Film/Nowplaying.js'
// import Comingsoon from '../views/Film/Comingsoon.js'
// import Login from '../views/Login.js'
import AuthComponent from './AuthComponent.js'
export default function MRouter() {
return (
<Routes>
<Route path='/films' element={LazyLoad("Film")}>
{/* 嵌套路由 */}
{/* index用于嵌套路由,仅匹配父路径时,设置渲染的组件。解决当嵌套路由有多个子路由但本身无法确认默认渲染哪个子路由的时候
可以增加index属性来指定默认路由。index路由和其他路由不同的地方是它没有path属性,他和父路由共享同一个路径。*/}
<Route index element={<Redirect to="nowplaying" />}></Route>
<Route path='nowplaying' element={LazyLoad("Film/Nowplaying")}></Route>
<Route path='comingsoon' element={LazyLoad("Film/Comingsoon")}></Route>
</Route>
<Route path='/center' element={
<AuthComponent>{LazyLoad("Center")}</AuthComponent>
}></Route>
<Route path='/cinemas' element={LazyLoad("Cinema")}></Route>
<Route path="/login" element={LazyLoad("Login")} />
{/* <Route path="/detail" element={<Detail />}></Route> */}
{/* 动态参数 */}
<Route path="/detail/:id" element={LazyLoad("Detail")}></Route>
{/* 对根路径进行重定向,可以使用自带的组件Navigate(需引入),也可以自己封装Redirect重定向组件 */}
<Route path='/' element={<Redirect to="/films" />}></Route>
{/* <Route path='/' element={<Navigate to="/films" />}></Route> */}
{/* 对其他非上述路由进行NotFound处理 */}
<Route path='*' element={LazyLoad("NotFound")}></Route>
</Routes>
)
}
//路由懒加载的封装
const LazyLoad = (path) => {
const Comp = React.lazy(() => import(`../views/${path}`))
return (
<React.Suspense fallback={<div>加载中....</div>}>
<Comp />
</React.Suspense>
)
}
useRoutes:
import React from 'react'
import { useRoutes } from 'react-router-dom'
import Redirect from './Redirect.js'
import AuthComponent from './AuthComponent.js'
// 类似于Vue的路由结构
export default function MRouter() {
const element = useRoutes([
{
path: "/films",
element: LazyLoad("Film"),
children: [
{
path: "",
element: <Redirect to="/films/nowplaying" />
},
{
path: "nowplaying",
element: LazyLoad("Film/Nowplaying")
},
{
path: "comingsoon",
element: LazyLoad("Film/Comingsoon")
}
]
},
{
path: "/cinemas",
element: LazyLoad("Cinema")
},
{
path: "/login",
element: LazyLoad("Login")
},
{
path: "/center",
element: <AuthComponent>
{LazyLoad("Center")}
</AuthComponent>
},
{
path: "/detail/:id",
element: LazyLoad("Detail")
},
{
path: "/",
element: <Redirect to="/films" />
},
{
path: "*",
element: LazyLoad("NotFound")
}
])
return (
element
)
}
//路由懒加载的封装
const LazyLoad = (path) => {
const Comp = React.lazy(() => import(`../views/${path}`))
return (
<React.Suspense fallback={<div>加载中....</div>}>
<Comp />
</React.Suspense>
)
}
路由重定向组件:
Redirect.js:
import { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
export default function Redirect({ to }) {
const navigate = useNavigate()
useEffect(() => {
navigate(to, { replace: true })
})
return
}
路由拦截组件:
import React from 'react'
import Redirect from './Redirect'
//路由拦截组件的封装
// 插槽传参,props.children
export default function AuthComponent({ children }) {
const isLogin = sessionStorage.getItem("token")
return isLogin ? children : <Redirect to="/login" />
}
以上就是router文件夹里面的
components文件夹中:
Tabbar组件:
import React from 'react'
import { NavLink } from 'react-router-dom'
import './Tabbar.css'
export default function Tabbar() {
return (
<div>
<ul>
<li>
<NavLink to="/films" className={({ isActive }) => isActive ? "active" : ""}>电影</NavLink>
</li>
<li>
<NavLink to="/cinemas" className={({ isActive }) => isActive ? "active" : ""}>影院</NavLink>
</li>
<li>
<NavLink to="/center" className={({ isActive }) => isActive ? "active" : ""}>我的</NavLink>
</li>
</ul>
</div>
)
}
withRouter组件:
import React from 'react'
import {
useNavigate,
useParams,
useLocation
} from 'react-router-dom'
// withRouter实现函数组件 与 类组件 传递路由信息
export default function withRouter(Component) {
return function (props) {
const push = useNavigate()
const match = useParams()
const location = useLocation()
return <Component {...props} history={{ push, match, location }} />
}
}
views文件夹中:
App文件:
import React from 'react'
import { HashRouter } from 'react-router-dom'
import Tabbar from '../../components/Tabbar'
import MRouter from '../../router'
export default function App() {
return (
<HashRouter>
<MRouter></MRouter>
<Tabbar></Tabbar>
</HashRouter>
)
}
Center文件:
import React from 'react'
export default function Center() {
return (
<div>Center</div>
)
}
Cinema文件:
import React from 'react'
export default function Cinema() {
return (
<div>Cinema</div>
)
}
Detail文件query传参:
import React from 'react'
import { useSearchParams } from 'react-router-dom'
export default function Detail() {
// query参数接收,和设置
const [searchParams, setSearchParams] = useSearchParams()
const query = searchParams.get("id")
console.log(query);
return (
<div>Detail
<button onClick={() => {
setSearchParams({ id: 1000 })
}}>点击</button>
</div>
)
}
Detail文件动态传参:
import React from 'react'
import { useParams, useNavigate } from 'react-router-dom'
export default function Detail() {
// params参数接收,和设置
const params = useParams()
const navigate = useNavigate()
console.log(params);
return (
<div>Detail
<button onClick={() => {
navigate("/detail/100")
}}>点击</button>
</div>
)
}
Film文件夹:
comingsoon文件:
import React from 'react'
export default function Comingsoon() {
return (
<div>Comingsoon</div>
)
}
filmitem类组件:
import React, { Component } from 'react'
import withRouter from '../../components/withRouter'
class Filmitem extends Component {
handleClick(id) {
// console.log(this.props.history)
// 这里就可以使用Router v5的一些语法(自定义)
this.props.history.push(`/detail/${id}`)
// this.props.history.push 跳转页面
// this.props.history.match 获取参数
// this.props.history.location 获取当前路由
}
render() {
return (
<li onClick={() => this.handleClick(this.props.filmId)}>
{this.props.name}
</li>
)
}
}
export default withRouter(Filmitem)
index文件:
import React from 'react'
import { Outlet } from 'react-router-dom'
export default function Film() {
return (
<div>
<div style={{ height: "200px", background: "yellow" }}>大轮播</div>
{/* 路由容器 相当于Vue中的 Router-view */}
<Outlet></Outlet>
</div>
)
}
nowplaying文件:
import axios from 'axios'
import React, { useState, useEffect } from 'react'
// import { useNavigate } from 'react-router-dom'
import Filmitem from './Filmitem'
export default function Nowplaying() {
const [list, setlist] = useState([])
// 只请求一次
useEffect(() => {
axios({
url: "https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=3818805",
headers: {
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.0","e":"16395416565231270166529","bc":"110100"}',
'X-Host': 'mall.film-ticket.film.list'
}
}).then(res => {
setlist(res.data.data.films)
})
}, [])
// const navigate = useNavigate()
// const handlePage = (id) => {
// navigate(`/detail/${id}`)
// }
return (
<div>
<ul>
{
list.map((item) => {
return (
<Filmitem key={item.filmId} {...item}></Filmitem>
)
})
}
</ul>
</div>
)
}
Login文件:
import React from 'react'
import { useNavigate } from 'react-router-dom'
export default function Login() {
const navigate = useNavigate()
return (
<div>
<input type="text" />
<button onClick={() => {
// 登录保存token,并跳转到我的页
sessionStorage.setItem("token", "kerwin")
navigate("/center")
}}>登录</button>
</div>
)
}
NotFound文件:
import React from 'react'
export default function NotFound() {
return (
<div>NotFound</div>
)
}