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)

效果:

react-ant 路由优化及封装,重定向,未找到路径跳到指定的页面,models的基本使用