import './App.css';
import { HashRouter } from 'react-router-dom';//路由模式BrowserRouter
import IndexRouter from './router/IndexRouter';
import Tabbar from './components/Tabbar/Tabbar';
function App() {
return (
<div className="App">
<li>dddd</li>
<HashRouter>
<IndexRouter></IndexRouter>
<Tabbar></Tabbar>
</HashRouter>
</div>
);
}
export default App;
src/router/IndexRouter.js
import React, { lazy, Suspense } from 'react'
import {Routes,Route,Navigate} from 'react-router-dom'
import Redirect from '../components/Redirect'
export default function IndexRouter() {
return (
<Routes>
{/* index等同于他的父级地址,这里等同于http://localhost:3000/ */}
{/* } /> */ }
<Route path='/films' element={LazyLoad('Films')}>
<Route index element={<Navigate to="/films/nowPlaying" />} />
{/* 嵌套路由需要在组件Films中配套Outlet(出口)一起使用 */}
<Route path='nowPlaying' element={LazyLoad('films/NowPlaying')} />
<Route path='/films/commingSoon' element={LazyLoad('films/CommingSoon')} />
</Route>
<Route path='/cinemas' element={LazyLoad('Cinemas')} />
<Route path='/login' element={LazyLoad('Login')} />
<Route path='/center' element={<AuthCom>{LazyLoad('Center')}</AuthCom>} />
{/* */}
<Route path='/detail/:id/:type' element={LazyLoad('DetailsParams')} />
{/* 重定向-Navigate:星号可以匹配任意地址*/}
{/* }/> */}
<Route path="/" element={<Redirect to="/films" />}/>
<Route path="*" element={LazyLoad('NotFound')}/>
</Routes>
)
}
//路由拦截
function AuthCom({children}){//props.children
const isLogin = window.localStorage.getItem('token');
return isLogin?children:<Redirect to="/login"/>
}
//路由懒加载,重定向的不用再调用懒加载函数
const LazyLoad = path => {
const Comp = lazy(()=>import('../views/'+path));
return (
<Suspense fallback={<>加载中。。。</>}>
<Comp/>
</Suspense>
)
}
import React, { lazy, Suspense } from 'react'
import {Routes,Route,Navigate, useRoutes} from 'react-router-dom'
import Redirect from '../components/Redirect'
export default function IndexRouter() {
const element = useRoutes([
{
path:'/films',
element:LazyLoad('Films'),
children:[
{
path:'',
element:<Navigate to="/films/nowPlaying" />
},
{
path:'nowPlaying',
element:LazyLoad('films/NowPlaying')
},
{
path:'/films/commingSoon',
element:LazyLoad('films/CommingSoon')
},
]
},
{
path:'/cinemas',
element:LazyLoad('Cinemas')
},
{
path:'/login',
element:LazyLoad('Login')
},
{
path:'/center',
element:<AuthCom>{LazyLoad('Center')}</AuthCom>
},
{
path:'/detail/:id/:type',
element:LazyLoad('DetailsParams')
},
{
path:'/',
element:<Redirect to="/films" />
},
{
path:'*',
element:LazyLoad('NotFound')
},
]);
return (
element
)
}
//路由拦截
function AuthCom({children}){//props.children
const isLogin = window.localStorage.getItem('token');
return isLogin?children:<Redirect to="/login"/>
}
//路由懒加载,重定向的不用再调用懒加载函数
const LazyLoad = path => {
const Comp = lazy(()=>import('../views/'+path));
return (
<Suspense fallback={<>加载中。。。</>}>
<Comp/>
</Suspense>
)
}
src/components/Redirect.js
import React, { useEffect } from 'react'
import {useNavigate} from 'react-router-dom'
export default function Redirect({to}) {
const Navigate = useNavigate();
useEffect(()=>{
Navigate(to,{replace:true});
},[]);
return null;
};
src/views/Films.js
import React from 'react'
import {Outlet} from 'react-router-dom'
export default function Films() {
return (
<div>
<div style={{height:"200px",background:"pink"}}>轮播</div>
{/* 这里会呈现 NowPlaying或commingSoon的内容 */}
<Outlet></Outlet>
</div>
)
}
src/components/Tabbar/Tabbar.js
import style from './Tabbar.module.css'
import React from 'react'
import {NavLink} from 'react-router-dom'
export default function Tabbar() {
return (
<div>
<ul>
<li>
{/* Link没有高亮className*/}
{/* 影院 */}
<NavLink to="/films" className={({isActive})=>isActive?style.tabActive:''}>电影</NavLink>
</li>
<li>
<NavLink to="/cinemas" className={({isActive})=>isActive?style.tabActive:''}>影院</NavLink>
</li>
<li>
<NavLink to="/center" className={({isActive})=>isActive?style.tabActive:''}>我的</NavLink>
</li>
</ul>
</div>
)
}
src/components/Tabbar/Tabbar.module.css
.tabActive{
color: pink;
}
/* 会影响全局,最好加自定义className */
li{
list-style: none;
}
src/views/films/NowPlaying.js
import React,{useState,useEffect} from 'react'
import axios
from 'axios';
import { useNavigate } from 'react-router-dom';
import FilmItem from '../../components/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=9261499",
method:'get',
headers:{
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16745641013679850669801473","bc":"110100"}',
'X-Host': 'mall.film-ticket.film.list'
}
}).then(res=>{
setList(res.data.data.films)
})
},[])
// const navigate = useNavigate();
// const handleChangePage = id => {
// //query-url传参
// // navigate(`/detail?id=${id}&type=2`)
// //路由传参
// navigate(`/detail/${id}/2`)
// }
return (
<div>
{
list.map(item=>{
return (
// handleChangePage(item.filmId)}>{item.name}
<FilmItem key={item.filmId} {...item} />
)
})
}
</div>
)
}
src/views/Details-searchParams.js
<Route path="/detail" element={<Detail/>} />
navigate(`/detail?id=${id}&type=2`)
import React from 'react'
import { useSearchParams } from 'react-router-dom'
export default function Details() {
const [searchParmas,setSearchParmas] = useSearchParams();
console.log(searchParmas.get('id'))//获取参数
console.log(searchParmas.has('name'))//判断是否有参数
return (
<div>
Details
<button onClick={()=>{
// 不能单独修改单个parmas
setSearchParmas({id:1000,type:1})//修改参数
}}>猜你喜欢</button>
</div>
)
}
src/views/Details-params.js
<Route path="/detail/:id/:type" element={<Detail/>} />
navigate(`/detail/${id}/2`)
import React from 'react'
import { useNavigate, useParams } from 'react-router-dom'
export default function Details() {
const params = useParams();
const navigate = useNavigate();
console.log(params.id)//获取参数
return (
<div>
Details
<button onClick={()=>{
navigate('/detail/1000/3')
}}>猜你喜欢</button>
</div>
)
}
import React from 'react'
import { useNavigate } from 'react-router-dom';
export default function Login() {
const navigate = useNavigate();
return (
<div>
<h1>登录页面</h1>
<input type="text" />
<button onClick={()=>{
localStorage.setItem('token',"xxx");
navigate('/center')
}}>登录</button>
</div>
)
}
import React from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
export default function withRouter(Component) {
return function(props){
const navigate = useNavigate();
const params = useParams();
const location = useLocation();
return <Component {...props} history={{navigate,params,location}}/>
}
}
import React from 'react'
import withRouter from './withRouter'
function FilmItem(props) {
const handleChangePage = id => {
props.history.navigate(`/detail/${id}/type=2`)//跳转页面
console.log(props.history.params)//获取参数对象
console.log(props.history.location)//获取当前路由
}
return (
<div>
<li onClick={() => handleChangePage(props.filmId)}>{props.name}</li>
</div>
)
}
export default withRouter(FilmItem)
import React from 'react'
import {useNavigate} from 'react-router-dom'
export default function App() {
const navigate = useNavigate()
return (
<div>
<button onClick={() => navigate(-2)}>Go 2 pages back</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>Go forward</button>
<button onClick={() => navigate(2)}>Go 2 pages forward</button>
</div>
)
}
import React, { lazy, Suspense, useEffect, useState } from 'react'
import {useRoutes} from 'react-router-dom'
import Redirect from '../components/Redirect'
import axios from 'axios';
const LocalRouterMap = {
"/home": 'NewsSandBox/Home/Home',
"/user-manage/list": 'NewsSandBox/user-manage/UserList',
"/right-manage/role/list": 'NewsSandBox/Right-manage/RoleList',
"/right-manage/right/list": 'NewsSandBox/Right-manage/RightList',
"/news-manage/add": 'NewsSandBox/news-manage/NewsAdd',
"/news-manage/draft": 'NewsSandBox/news-manage/NewsDraft',
"/news-manage/category": 'NewsSandBox/news-manage/NewsCategory',
"/news-manage/preview/:id": 'NewsSandBox/news-manage/NewsPreview',
"/news-manage/update/:id": 'NewsSandBox/news-manage/NewsUpdate',
"/audit-manage/audit": 'NewsSandBox/audit-manage/Audit',
"/audit-manage/list": 'NewsSandBox/audit-manage/AuditList',
"/publish-manage/unpublished": 'NewsSandBox/publish-manage/Unpublished',
"/publish-manage/published": 'NewsSandBox/publish-manage/Published',
"/publish-manage/sunset": 'NewsSandBox/publish-manage/Sunset',
};
export default function IndexRouter() {
const [element,setElement] = useState([]);
useEffect(()=>{
let NewsRouter = [];
Promise.all([axios.get("/rights"), axios.get("/children")]).then((res) => {
let backRouteList = [...res[0].data, ...res[1].data];
backRouteList.forEach(item=>{
//有页面权限和角色人员权限
if(LocalRouterMap[item.key] && (item.pagepermisson || item.routepermisson)){
NewsRouter.push(
{
path:item.key,
element: LazyLoad(LocalRouterMap[item.key])
}
)
}
});
let hasNPRoute = NewsRouter.length > 0 ? [{path:'*',element:LazyLoad('NewsSandBox/Nopermission/Nopermission')}]:[];
setElement(
[
{
path:'/login',
element:LazyLoad('Login/Login'),
},
{
path:'/news',
element:LazyLoad('News/News'),
},
{
path:'/detail/:id',
element:LazyLoad('News/Detail'),
},
{
path:'/',
element:<AuthCom>{LazyLoad('NewsSandBox/NewsSandBox')}</AuthCom>,
children:[
...NewsRouter,
{
path:'',
element:<Redirect to="/home" />,
},
...hasNPRoute
]
},
{
path:'/TestAsyncRedux',
element:LazyLoad('Test-AsyncRedux')
},
{
path:'/TestCreateAsyncThunk',
element:LazyLoad('Test-CreateAsyncThunk')
},
{
path:'/CreateSelector',
element:LazyLoad('Test-CreateSelector')
},
]
);
});
},[]);
const routes = useRoutes(element)
return (
routes
)
}
//路由拦截
function AuthCom({children}){//props.children
const isLogin = window.localStorage.getItem('token');
return isLogin?children:<Redirect to="/login"/>
}
//路由懒加载,重定向的不用再调用懒加载函数
const LazyLoad = path => {
const Comp = lazy(()=>import('../views/'+path));
return (
<Suspense fallback={<>加载中。。。</>}>
<Comp/>
</Suspense>
)
}