引言
习惯了vue的小伙伴可能对react中路由的使用感到不习惯。在vue中,我们可以下面的方式配置路由并绑定组件。
export default new Router({
mode: 'history',
routes: [
{
path: '/',
redirect: {
name: 'index'
}
},
{
path: '/index',
name: 'index',
component: () => import('@/views/Index.vue'),
children: [
{
path: '/interviewRecord',
name: 'interviewRecord',
meta: {
isLogin: true,
title: '面试记录'
},
component: () => import('@/views/interviewRecord/Index.vue'),
},
]
},
{
path: '/login',
name: 'login',
component: () => import('@/views/Login.vue')
}
]
})
并在页面中用<vue-router>
给路由组件占位。这使得不同页面的嵌套路由结构十分直观地展现在Router的配置中
而在react中,我们需要在页面中引入并绑定路由组件,比如这样
import React, { Component } from "react";
import { BrowserRouter, Link, Switch, Route } from "react-router-dom";
import Category from "./category";
import User from "./user";
import Article from "./article";
class Home extends Component {
state = {};
render() {
return (
<BrowserRouter>
<div className="home">
<header className="header">头部</header>
<div className="container">
<nav className="left">
<Link to="/category">栏目管理</Link>
<Link to="/article">文章管理</Link>
<Link to="/user">用户管理</Link>
</nav>
<div className="right">
<Route path="/category" component={Category}></Route>
<Route path="/article" component={Article}></Route>
<Route path="/user" component={User}></Route>
</div>
</div>
</div>
</BrowserRouter>
);
}
}
export default Home;
我个人并不喜欢这种方式,如果存在多级的嵌套路由,则需要在多个页面中引入组件绑定路由。所以我自己按照vue-router的用法封装了react的路由。
封装
配置文件
我们先按照vue-router的配置,将react的路由也抽象成一个列表。比如下面这样
import Article from "@v/article/Index";
import Category from "@v/category/Index";
import User from "@v/user/Index";
import Index from "@v/index/Index";
import Login from "@v/login/Index";
import ArticlePassed from "@v/article/passed/Index";
const router = [
{
path: "/login",
component: Login,
},
{
path: "/",
component: Index,
children: [
{
path: "/article",
component: Article,
children: [
{
path: "/article/passed",
component: ArticlePassed,
},
],
},
{
path: "/category",
component: Category,
},
{
path: "/user",
component: User,
},
],
},
];
export default router;
封装的路由组件
有了这个配置列表,我们需要一个组件能将这个配置列表转化为react能认识的<Route>
组件
import React from "react";
import { Route, Switch } from "react-router-dom";
const RouterView = (props) => {
return (
<Switch>
{props.routes.map((item, index) => {
return (
<Route
key={index}
path={item.path}
exact={item.exact}
render={(routeProps) => {
// 判断是否存在子路由
if (item.children) {
return <item.component {...routeProps} routes={item.children} />;
} else {
return <item.component {...routeProps} />;
}
}}
/>
);
})}
</Switch>
);
};
export default RouterView;
在配置列表遍历的时候,对于存在子路由的组件,我们需要将该路由的children传递给该组件。
使用
import React, { Component } from "react";
import { BrowserRouter } from "react-router-dom";
import RouterView from "../router/index";
import config from "../router/config";
import "antd/dist/antd.css";
export default class App extends Component {
render() {
return (
<div className="App">
<BrowserRouter>
<RouterView routes={config} />
</BrowserRouter>
</div>
);
}
}
在使用时,我们只需要引入封装的RouterView组件和配置列表config,存在子路由时,我们需要在该组件中再次引入RouterView,并将传递过来的子路由信息赋给组件。
render() {
const { routes } = this.props;
return (
<RouterView routes={routes} />
)
这样我们就获得一个使用方式和vue-router基本一致的react路由组件。
demo地址
如果有需要,可以上gitee拉我的代码,我正在搭建一个react的脚手架,地址:https://gitee.com/yu-zhuohao/react_management_frame