central-react-router
v0.1.16
Published
实现类似umi的集中式路由配置
Downloads
7
Readme
central-react-router
作用
实现类似umi的集中式路由配置
主要技术
react-router-dom 5.x
引入方式
yarn add central-react-router
p.s. 使用该组件时, 需要在webpack中配置@
别名, 使其指向src
目录, 否则会出现module not found的错误
路由配置说明
路由配置数据结构
wrappers配置特别说明:
不能在有子路由的路由配置上使用wrappers配置,即使配置了,也会被忽略: 因为在有子路的路由配置上使用wrapper会导致: Can‘t perform a React state update on an unmounted component. This is a no-op... 异常
export interface RvcRouteConfig {
/**
* 路由名
*/
path: string;
/**
* 匹配到当前路由之后,要跳转的路由
*/
redirect?: string;
/**
* 是否精确匹配. 默认: true
*/
exact?: boolean;
/**
* <strong>不需要懒加载的路由绑定模块</strong>
* <p>
* 如:已经引入了Home组件, 则component填 Home
* </p>
* <strong>需要懒加载的路由绑定模块.</strong>
* <p>
* 所有的路由都是以src为根目录.
* </p>
* <p>
* 如果你有个模块:src/Home, 则component填'Home'
* </p>
* <p>
* 如果你有个模块:src/pages/Test, 则component填'pages/Test'
* </p>
*/
component?: any;
/**
* 子路由
*/
routes?: RvcRouteConfig[],
/**
* 是否将path值作为key. 默认为:true. 为true时, 路由的key为path值, 否则为路由的索引值
*/
pathAsKey?: boolean,
/**
* 路由挂载组件的高阶组件封装, 可以用来实现鉴权. 所有高阶组件都使用懒加载. 高阶组件会从右到左开始逐层包装, 只有当前这一层执行通过, 才会继续执行下一层
* <br/>
* <strong>不能在有子路由的路由配置上使用wrappers配置,即使配置了,也会被忽略: 因为在有子路的路由配置上使用wrapper会导致: Can‘t perform a React state update on an unmounted component. This is a no-op... 异常</strong>
* <p>
* 所有的路由都是以src为根目录.
* </p>
* <p>
* 如果你有个模块:src/Home, 则component填'Home'
* </p>
* <p>
* 如果你有个模块:src/pages/Test, 则component填'pages/Test'
* </p>
*/
wrappers?: string[]
}
路由配置示例
// router.config.ts
import App from "../App";
import {RvcRouteConfig} from "../utils/lazyRoute/renderRoutesMap";
import Login from "../pages/Login";
const routes: RvcRouteConfig[] = [
{path: '/', component: App},
{path: '/login', component: Login},
// wrappers 会从右到左开始逐层包装, 只有所有wrapper都执行成功, 最后才会渲染 MyHome 组件
{
path: '/MyHome',
component: 'pages/MyHome',
wrappers: ['wrappers/AuthWrapper', 'wrappers/LoginValidateWrapper', 'wrappers/OtherWrapper']
},
//嵌套路由
{
path: '/home', component: 'pages/Home', exact: false,
routes: [
{path: "/home", redirect: '/home/01'},
{path: "/home/01", component: 'pages/Children01'},
{path: "/home/02", component: 'pages/Children02'},
]
},
]
export default routes;
使用示例
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {store} from './app/store';
import {Provider} from 'react-redux';
import * as serviceWorker from './serviceWorker';
import routes from "./router/router.config";
import {RenderHashRoutes, RenderBrowserRouter, RenderStaticRouter} from "./utils/lazyRoute/renderRoutes";
// hash路由方式
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<RenderHashRoutes routes={routes}/>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
// brower路由方式
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<RenderBrowserRouter routes={routes}/>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
// 服务器渲染路由方式
app.use((req, res, next) => {
if (req.url.startsWith('/user/') || req.url.startsWith('/static/')) {
return next()
}
const context = {}
const frontComponents = renderToString(
(<Provider store={store}>
<RenderStaticRouter
location={req.url}
context={context}
routes={routes}
/>
</Provider>)
)
res.send(frontComponents)
})
嵌套路由
import React, {FC, useEffect, useState} from 'react';
import {Link, NavLink} from "react-router-dom";
import renderRoutesMap from "../utils/lazyRoute/renderRoutesMap";
interface HomeProps {
}
const Home: FC<HomeProps> = (props) => {
const [count, setCount] = useState<number>(0);
console.log('props', props)
// @ts-ignore
const route = props.route;
// @ts-ignore
const routes = props.route?.routes;
useEffect(() => {
console.log('Home 组件挂载完毕!');
}, [route]);
console.log('Home 组件render!');
return (
<div key={1}>
<Link to={'/MyHome'}>MyHome</Link>
<br/>
<div>Home 组件</div>
{count}
<br/>
<button onClick={() => setCount(prevState => prevState + 2)}>+2</button>
<br/>
<NavLink to={'/home/01'}>Children01</NavLink>
<br/>
<NavLink to={'/home/02'}>Children02</NavLink>
{renderRoutesMap(routes)}
</div>
);
};
export default Home;
/**
* 路由组件公共属性
*/
export interface RouteCompProps {
history: H.History;
location: H.Location;
match: match;
}
// history.push 与 history.replace 的区别
history.push('xxx'); //将当前路由记录历史, 当前界面转入新路由, 可回退到上一个路由
history.replace('xxx');// 当前路由不记录历史, 当前界面转入新路由, 不可回退到上一个路由
源代码仓库
https://gitee.com/free_pan/central-react-router.git