react-ant 路由优化及封装,重定向,未找到路径跳到指定的页面,models的基本使用
仓库地址:https://gitee.com/zhouyunfang/react-ant/tree/4-route-encapsul
修改相关文件:
1. reouter.js(路由优化页面)
2. utils/SubRoutes.js(路由封装页面)
3. pages/IndexPage.js(首页)
4. src/components/NoMatch.js(用于地址栏上手动输入不存在的页面指定跳转的地方)
5. models/home.js(router.js中用到的models配置走到models/home.js(用于数据状态管理))
6. pages/home.js (在这个页面获取models/home.js中的text属性值进行渲染)
reouter.js
import React from 'react';
import { Router, Switch } from 'dva/router';
// 引入utils/SubRoutes.js中封装好的路由调用方法
import SubRoutes from './utils/SubRoutes'
// 路由优化
const RouteConfig = [
{ // 设置根路径
path:'/',
component:()=>import('./pages/IndexPage'),
model:[],//引入./models/global.js中state状态信息,通过subRoutes.js传递给到Indexpage.js中使用
routes:[//其它路由
{
path:"/home",
component:()=>import('./pages/Home'),
redirect:true, //重定向跳转
model:[import('./models/home')],
},
{
path:"/menus",
component:()=>import('./pages/Menus'),
model:[],
},
{
path:"/about",
component:()=>import('./pages/About'),
model:[],
},
{
path:"/admin",
component:()=>import('./pages/Admin'),
model:[],
},
{
path:"/login",
component:()=>import('./pages/User/Login'),
model:[],
},
{
path:"/register",
component:()=>import('./pages/User/Register'),
model: [],
},
]
}
]
function RouterConfig({ history,app }) {
// console.log(app)
return (
<Router history={history}>
<Switch>
{
RouteConfig.map((route,i) =>(/* 调用在utils中封装的组件,把 RouteConfig中定义的所有路由传入 ,进行渲染*/
<SubRoutes key={i} {...route} app={app} />
))
}
</Switch>
</Router>
);
}
export default RouterConfig;
utils/SubRoutes.js
import React from 'react'
import dynamic from 'dva/dynamic';
import {Route , Redirect} from 'dva/router'
import NoMatch from '../components/NoMatch'
/**解决组件动态加载路由问题的 util 方法。
* app: dva 实例,加载 models 时需要
* models: 返回 Promise 数组的函数,Promise 返回 dva model
* component:返回 Promise 的函数,Promise 返回 React Component
* 效果比如:router.js component:()=>import('./pages/IndexPage'),
* */
const dynamicCom = (routes,component,app,models)=>dynamic({
app,
models: () =>models,//在router.js中的model传的什么这里就接收什么
component: () =>
component().then(res =>{
// console.log(res)
const Component = res.default || res;
// 把组件加载出来
return props =><Component {...props} app={app} routes={routes}/>
})
});
//优化封装
export default function SubRoutes({app, model, component, routes}) {//接收router.js页面传入的route,之后在页面中使用
//渲染路由
//component 用于渲染 routes = {route.routes}传过来的路由
return (
<Route component={dynamicCom(
routes,
component,
app,
model
)}/>
)
}
// 重定向组件
export function RedirectRoute({routes,from,exact}) {
const routeR = routes.filter(item =>{//过滤出redirect
return item.redirect;
})
// 对routeR返回(数组)如果没有值就输出一个传入的path路径
const to = routeR.length ? routeR[0].path :routes[0].path;
return <Redirect exact={exact} from={from} to={to}/>
}
// 针对找不到的地址进行封装
export function NoMatchRoute({status = 404}){
return <Route render={props => (<NoMatch {...props} status ={status}/> )} />
}
src/components/NoMatch.js
import React from 'react'
export default function index({status}) {
return (
<h1>
{status} 未找到该页面
</h1>
)
}
pages/IndexPage.js
import React from 'react';
import { connect } from 'dva';
import { Layout } from 'antd';
// 引入路由需要的组件,switch为选择Route, Redirect 其中一个使用
import { Switch } from 'dva/router';
import styles from './IndexPage.scss';
import NavBar from './NavBar'
// 引入封装的路由,封装好的重定向
import SubRoutes, {RedirectRoute,NoMatchRoute} from '../utils/SubRoutes'
const { Header, Content } = Layout;
function IndexPage(props) {
// console.log(props) 打印出来的location/pathname传入子组件,props为SubRoutes.js传过来的路由
const {routes,app} = props;
// console.log(routes)//所有路由路径
return (
<Layout className={styles.layout}>
<Header className={styles.header}>
<NavBar {...props}/>
</Header>
<Content className={styles.content}>
{/* 显示对应的页面,使用动态路由,对解构出来的路由遍历 */}
<Switch>
{routes.map((route,i) =>(
/* 调用封装好的路由优化组件 ,传递个数和所有路由*/
<SubRoutes key={i} {...route} app={app}/>
))}
{/* 调用封装过的重定向 重定向只有一个*/}
<RedirectRoute exact={true} from="/" routes={routes} />
{/* 对地址栏上找不到的地址跳转到指定的地方 */}
<NoMatchRoute />
</Switch>
{/* <h1>{props.text}</h1> */}
</Content>
</Layout>)
;
}
IndexPage.propTypes = {
};
export default connect()(IndexPage);
models/home.js
export default {
namespace: 'home',
state: {
text:'我在model.js/home.js中'
},
subscriptions: {
},
effects: {
},
reducers: {
},
};
pages/home.js
import React from 'react'
// 要获取route.js中的models值就要引入connect
import { connect } from 'dva';
import style from './index.scss';
function index(props) {
return (
<div className={style.home}>
<div className={style.background}>
<h1 >你们的餐厅</h1>
<h1>{props.text}</h1>
</div>
</div>
)
}
// 关联home.js(model) 和 当前的组件index.js(home 组件) ...home 从中获取当前的home/text内容
export default connect(({ home }) => ({ ...home }))(index)
效果: