这篇文章主要介绍了react自动化构建路由的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
正文
react自动化构建路由的实现
序
在使用react-router-dom在编写项目的时候有种感觉就是,使用起来非常的方便,但是若是维护起来,那便是比较麻烦了,因为各大路由分散在各个组件中. 所以我们就会想到,使用react-router-dom中提供的config模式来编写我们的路由,这样写的好处就是我们可以将逻辑集中在一处,配置路由比较方便
项目地址
https://gitee.com/d718781500/autoRouter
1.路由集中式
我们先将下列数据定义在/src/router/index.js中
在react的路由官方文档中就提供了配置集中式路由的案例,大致是这样的仿照vue的路由,生成一个配置文件,预期是这样的
//需要一个路由的配置,它是一个数组
import Discover from "../pages/Discover"
import Djradio from "../pages/Discover/Djradio"
import Playlist from "../pages/Discover/Playlist"
import Toplist from "../pages/Discover/Toplist"
import Friends from "../pages/Friends"
import Mine from "../pages/Mine"
import Page404 from "../pages/Page404"
const routes = [
{
path: "/friends",
component: Friends
},
{
path: "/mine",
component: Mine
},
{
path: "/discover",
component: Discover,
children: [
{
path: "/discover/djradio",
component: Djradio
},
{
path: "/discover/playlist",
component: Playlist
},
{
path: "/discover/toplist",
component: Toplist
}
]
},
{//Page404这个配置一定要在所有路由配置之后
path: "*",
component: Page404
}
]
export default routes
我们可以通过上述配置,来生成一个路由.当然上述的配置也只是做了简单的处理,还有redirect exact等属性没有写,我们还是从一个简单的开始吧
2.文件目录
上述的配置中使用了类似于vue的集中式路由配置模式,那么下面就展示下我当前这个demo的结构目录吧
项目目录结构

src/pages目录结构
├─Discover
│ │ abc.js
│ │ index.js
│ │
│ ├─Djradio
│ │ │ index.js
│ │ │ lf.js
│ │ │
│ │ └─gv
│ │ index.js
│ │
│ ├─Playlist
│ │ index.js
│ │
│ └─Toplist
│ index.js
│
├─Entertaiment
│ index.js
│
├─Friends
│ index.js
│ xb.js
│
├─Mine
│ index.js
│
└─Page404
index.js
有了这些结构之后,那么在1中提到的引入文件结合起来看就不懵逼啦,接下来我们可以封装一个组件,给他取个名字叫做CompileRouter这个组件专门用于编译路由
3.创建CompileRouter

这个组件我们把它创建在src/utils中,作用就是通过传入的路由配置,然后计算出这个组件,那么问题来了,为什么要创建这个组件呢?
让我们回顾一下react路由的编写方式吧,react路由需要一个基础组件HashRouter或者BrowserRouter这两个相当于一个基石组件
然后还需要一个路由配方这个组件可以接受一个path映射一个component
我们来写段伪代码来说明一下
//引入路由基本组件(要在项目中安装 npm i react-router-dom)
import {HashRouter as Router,Route} from "react-router-dom"
class Demo extends React.Component {
render(){
//基石路由
<Router>
//路由配方组件 通过path匹配component
<Route path="/" component={Home}/>
<Route path="/mine" component={Mine}/>
</Router>
}
}
这是基本用法,所以我们CompileRouter这个组件的工作就是,生成如上代码中的Route一样,生成Route然后展示在组件上
在了解到Compile的基本作用之后,下面我们就开始编码吧
我个CompileRouter设计是接受一个数据,这个数据必须是符合路由配置的一个数组,就像1里代码中所示的数组一样,接受的属性为routes
//这个文件通过routes配置来编译出路由
import React from "react"
import { Switch, Route } from "react-router-dom";
export default class CompileRouter extends React.Component {
constructor() {
super()
this.state = {
c: []
}
}
renderRoute() {
let { routes } = this.props;//获取routes路由配置
//1.通过routes生成Route组件
//确保routes是一个数组
// console.log(routes)
//render 不会重复让组件的componentDidMount和componentWillUnmount重复调用
if (Array.isArray(routes) && routes.length > 0) {
//确保传入的routes是个数组
// 循环迭代传入的routes
let finalRoutes = routes.map(route => {
//每个route是这个样子的 {path:"xxx",component:"xxx"}
//如果route有子节点 {path:"xxx",component:"xxx",children:[{path:"xxx"}]}
return <Route path={route.path} key={route.path} render={
// 这么写的作用就是,如果路由还有嵌套路由,那么我们可以把route中的children中的配置数据传递给这个组件,让组件再次调用CompileRouter的时候就能编译出嵌套路由了
() => <route.component routes={route.children} />
} />
})
this.setState({
c: finalRoutes
})
} else {
throw new Error("routes必须是一个数组,并且长度要大于0")
}
}
componentDidMount() {
//确保首次调用renderRoute计算出Route组件
this.renderRoute()
}
render() {
let { c } = this.state;
return (
<Switch>
{c}
</Switch>
)
}
}
上述代码就是用于去处理routes数据并且声称这样的组件,每一步的作用我都已经在上面用注释标明了
4.使用CompileRouter
其实我们可以把封装的这个组件当成是vue-router中的视图组件<router-view/>就暂且先这么认为吧,接下来我们需要在页面上渲染1级路由了
在src/app.js
import React from "react"
import { HashRouter as Router, Link } from "react-router-dom"
//引入我们封装的CompileRouter罪案
import CompileRouter from "./utils/compileRouter"
//引入在1中定义的路由配置数据
import routes from "./router"
console.log(routes)
class App extends React.Component {
render() {
return (
<Router>
<Link to="/friends">朋友</Link>
|
<Link to="/discover">发现</Link>
|
<Link to="/mine">我的</Link>
{/*当成是vue-router的视图组件 我们需要将路由配置数据传入* 2 本站永久网址:http://www.sddll.com
3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权进行删除处理。
4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
6 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。

发表评论