鸽了一段时间,终于回归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>
                &nbsp;
                <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>
        &nbsp;
        <NavLink to="/login">Login</NavLink>
        &nbsp;
        <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();

搞定。。。。。。。
有问题请留言,因为代码量少,所以没有源代码下载

Logo

前往低代码交流专区

更多推荐