React 路由 封装
React 路由 封装主要目录路由列表在App.jsx页面引用路由组件注意鸽了一段时间,终于回归React的阵营中,后面会完整制作一个项目,今天先讲一下路由,后续会和项目一并讲解。主要目录我发现很多博主讲封装,一是转载别人的,二又不说明 哪个打哪个文件的代码,云里雾里。我们一般把 页面组件(页面)放到 component 里面的 pages 里,相当于 vue 的 view文件,因为在React里
React 路由 封装
鸽了一段时间,终于回归React的阵营中,后面会完整制作一个项目,今天先讲一下路由,后续会和项目一并讲解。
主要目录
我发现很多博主讲封装,一是转载别人的,二又不说明 哪个打哪个文件的代码,云里雾里。
我们一般把 页面组件(页面)放到 component 里面的 pages 里,相当于 vue 的 view文件,因为在React里面,页面也算是组件,所以,pages 理应放到 component 里面。
我们每创建一个页面都必须先创建文件夹,然后创建 index.js/index.jsx ,这样既方便我们添加单独页面的样式(如,在Index文件里创建多一个index.css),又方便我们添加页面的 子页面(如Test)。
router文件中,
config.jsx 用于存放我们的路由列表,
index.jsx 是路由组件的入口
router-view.jsx 是我们每一个 Router 的封装,后面会讲到。
路由列表
config.jsx
import { lazy } from 'react'
const routes = [
{
path: '/test',
component: lazy(() => import('../pages/Test')),
meta: {
title: '测试页面'
},
// 若有子页面,此为参考
routes: [
{
path: '/test/demo',
component: lazy(() => import('../pages/Test/Demo'))
},
{
path: '/test/demo2',
component: lazy(() => import('../pages/Test/Demo2'))
}
]
},
{
path: '/index',
component: lazy(() => import('../pages/Index')),
// 如果要求严格路径
isExact: true,
meta: {
title: '首页'
}
},
{
path: '/login',
component: lazy(() => import('../pages/Login')),
meta: {
title: '登录页面'
}
},
{
path: '/',
component: lazy(() => import('../pages/Index')),
meta: {
title: '首页'
}
},
{
path: null,
redirect: lazy(() => import('../pages/NotFound')),
meta: {
title: '404'
}
},
]
export default routes
这里尽量做得与vue路由格式一样
lazy嘛,顾名思义懒加载
写这个路由列表,目的只是为了后期方便添加修改页面
index.jsx
import React from 'react'
import routes from './config' // 路由列表,有其他的路由列表页面可以继续引入
import RouterView from './router-view' // 封装好的 Router
const routerList = [ // 将所有路由拼接在一起
...routes
]
const ViewRouter = () => {
return (
<div>
<RouterView route={routerList} /> // 调用封装好的 Router
</div>
)
}
export default ViewRouter
我们的目的是将繁琐的路由封装成类似于 vue 的 <view-router />
一样简单实用
router-view.jsx
import {
Switch,
Redirect,
Route
} from "react-router-dom"; // 引入 react-router-dom
import { Suspense } from 'react' // Suspense 配合前面的 laze() 使用,不加上会报错
const RouterView = (props) => {
let { route } = props // 拿到index.jsx页面传过来的 路由列表
return (
<Suspense fallback={<div>Loading...</div>}> // 加载时的dom
<Switch>
{
route.map((item, index) => {
return item.component ? <Route key={index} path={item.path} render={(props) => {
return <item.component route={item.routes} {...props} />
}}></Route> : <Redirect key={index} from={item.path} to={item.redirect} /> // 找不到对应的路由时 全部去到404页面
})
}
</Switch>
</Suspense>
)
}
export default RouterView
这边 首先通过 map() 遍历 Route ,按照路由表格式传递参数。这里用 render 而不是直接 component={} ,是因为我们可能有 嵌套子页面的需求。一样的,把routes (根据路由表的子页面list)传进去,这样就完成了整个 Route 的封装,无论我们有多少个嵌套子页面,都可以直接使用。
正常来说,我们得先创建页面,不然,路由页面那边会报错,那么我们就把页面简单过一下:
Index/index.jsx
import React, { Component } from 'react'
export default class index extends Component {
goRouter = (path) => {
return () => {
this.props.history.push({
pathname: path,
state: null
})
}
}
render() {
return (
<div>
<h3>index页面</h3>
<div onClick={this.goRouter('/login')}>Go Login</div>
</div>
)
}
}
这里说一下跳转,react的跳转不仅局限于 Link/NavLink 的跳转,我们在高阶函数里,通过 this.props.history.push()【带痕迹】/ this.props.history.replace()【痕无迹】
Login/index.jsx
import React, { Component } from 'react'
export default class login extends Component {
goRouter = (path) => {
return () => {
this.props.history.push({
pathname: path,
state: null
})
}
}
render() {
return (
<div>
<h3>login页面</h3>
<div onClick={this.goRouter('/index')}>Go Index</div>
</div>
)
}
}
NotFound/index.jsx
import React, { Component } from 'react'
export default class NotFound extends Component {
render() {
return (
<div>
404
</div>
)
}
}
404页面按自己的来
Test/index.jsx
import React, { Component } from 'react'
import { NavLink } from 'react-router-dom'
import RouterView from '../../router/router-view'
export default class test extends Component {
render() {
let {route} = this.props
return (
<div>
<br />
这是测试页面
<br />
<br />
<NavLink to="/test/demo">demo</NavLink>
<NavLink to="/test/demo2">demo2</NavLink>
<br />
<br />
<RouterView route={route} />
</div>
)
}
}
test页面是为了让大家更好理解 嵌套子页面做的一个例子
因为Text/idnex.jsx 页面本身就是个页面组件,我们在 router-view.jsx 页面里就已经往里面传了 route
return <item.component route={item.routes} {...props} />
所以我们是可以直接在 Text/index.jsx里面 直接拿到route
let {route} = this.props
所以我们直接引用
import RouterView from '../../router/router-view'
并调用即可
<RouterView route={route} />
Text/Demo/index.jsx
import React, { Component } from 'react'
export default class demo extends Component {
render() {
return (
<div>
<h2>这是测试页面的子页面测试</h2>
</div>
)
}
}
Text/Demo2/index.jsx
import React, { Component } from 'react'
export default class demo2 extends Component {
render() {
return (
<div>
<h2>这是测试页面的子页面测试2</h2>
</div>
)
}
}
在App.jsx页面引用路由组件
惯例先上代码
App.jsx
import { NavLink } from 'react-router-dom'
import ViewRouter from './router/index' // 封装好的路由
import './App.css';
function App() {
return (
<div className="App">
<div className="nar">
<NavLink to="/index">Index</NavLink>
<NavLink to="/login">Login</NavLink>
<NavLink to="/test">test</NavLink>
</div>
<div className="content">
<ViewRouter />
</div>
</div>
);
}
export default App;
就是一个引入并调用
注意
我们的路由是被 整个 BrowserRouter包裹起来才能生效,所以我们最后一步,直接在 index.js 页面加上
import React from 'react';
import ReactDOM from 'react-dom';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter as Router } from 'react-router-dom' // BrowserRouter
import App from './App';
ReactDOM.render(
<Router> // 直接把整个App包裹起来
<App />
</Router>,
document.getElementById('root')
);
reportWebVitals();
搞定。。。。。。。
有问题请留言,因为代码量少,所以没有源代码下载
更多推荐
所有评论(0)