0.1.16 • Published 3 years ago

central-react-router v0.1.16

Weekly downloads
281
License
MIT
Repository
-
Last release
3 years ago

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

0.1.15

3 years ago

0.1.16

3 years ago

0.1.14

3 years ago

0.1.10

3 years ago

0.1.11

3 years ago

0.1.12

3 years ago

0.1.13

3 years ago

0.1.9

3 years ago

0.1.8

3 years ago

0.1.7

3 years ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.4

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago