手牵手学习react之左侧导航栏路由封装(七)

前言

后台管理系统是前端永远绕不开的话题,无论技术怎么革新,检验技术最好的标准就是如何做好产品。如今的前端可谓是百花齐放,百家争鸣,甚至学不过来了!吐血~ 本节主要讲述如何使用react、react-router-dom封装侧边栏。

介绍

下载react-router-dom

yarn add react-router-dom

react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能:

  • Link组件,会渲染一个a标签;

  • BrowserRouter组件,使用pushStatepopState事件构建路由;

  • HashRouter组件,使用window.location.hashhashchange事件构建路由。

  • react-router-native: 基于react-router,类似react-router-dom,加入了react-native运行环境下的一些功能。

开始

 描述:图例就是简单的后台管理系统模板,左侧的导航栏通过路由控制内容区域的显示。页面过于简单,后面会重新替换,见谅!项目的ui是基于antD。

  • 新建views文件夹放置页面
  • 在views下分模块放置各类页面(首页:home)
import React, { Component } from "react";
// layout组件
import LayoutAside from "./components/aside";
import LayoutHeader from "./components/header";
import ContainerMain from "../../components/containerMain/Index";
// css
import "./layout.scss";
// antD
import { Layout } from "antd";
const { Sider, Header, Content } = Layout;

export default class Index extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <Layout className="layout-wrap">
        <Header className="layout-header">
          <LayoutHeader />
        </Header>

        <Layout>
          <Sider className="layout-side">
            <LayoutAside />
          </Sider>
          <Content className="layout-main">
            <ContainerMain />
          </Content>
        </Layout>
      </Layout>
    );
  }
}

描述:首页是由登录页面进来的。我们从外部引入三个组件LayoutAside、LayoutHeader、ContainerMain,分别展示侧边栏、头部、内容区。

  • LayoutAside
import React, { Component } from "react";

//asideMenu
import AsideMenu from "../../../components/asideMenu/index";

export default class Aside extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return <AsideMenu />;
  }
}
  •  LayoutHeader
import React, { Component, Fragment } from "react";

//css
import "./aside.scss";

export default class Header extends Component {
  constructor(prpos) {
    super(prpos);
    this.state = {};
  }

  render() {
    return (
      <Fragment>
        <h1 className="logo">
          <span>LOGO</span>
        </h1>
      </Fragment>
    );
  }
}
  • ContainerMain 
import React, { Component, Fragment } from "react";
import { Switch } from "react-router-dom";
//组件
import User from "../../views/user/index";
import UserAdd from "../../views/user/Add";
//私有路由组件
//私有组件方法
import PrivateRouter from "../privateRouter/index";

export default class ContainerMain extends Component {
  constructor(prpos) {
    super(prpos);
    this.state = {};
  }

  render() {
    return (
      <Fragment>
        <Switch>
          <PrivateRouter exact path="/home/user/list" component={User}></PrivateRouter>
          <PrivateRouter exact path="/home/user/add" component={UserAdd}></PrivateRouter>
        </Switch>
      </Fragment>
    );
  }
}

描述:这个页面是根据路由来展示不同的页面,里面引入私有组件方法匹配路由。

  • PrivateRouter 
import React from "react";
import { Route, Redirect } from "react-router-dom";
//获取token
import { getToken } from "../../utils/session";

const PrivateRouter = ({ component: Component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={
        (routePrpos) =>
          getToken() ? <Component {...routePrpos} /> : <Redirect to="/" /> //判断token,是否重定向到登录页
      }
    />
  );
};

export default PrivateRouter;

描述:这个私有组件是react-router-dom官方提供的,我们在这个方法中做了路由重定向,防止通过路径访问。

  • AsideMenu 
import React, { Component, Fragment } from "react";
import { Link } from "react-router-dom";

//antd
import { UserOutlined } from "@ant-design/icons";
import { Menu } from "antd";

//路由
import Router from "../../router/index";

const { SubMenu } = Menu;

export default class AsideMenu extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  // 无子级菜单处理
  renderMenu = ({ title, key }) => {
    return (
      <Menu.Item key={key}>
        <Link to={key}>{title}</Link>
      </Menu.Item>
    );
  };

  // 子级判断处理(递归)
  renderSubMenu = ({ title, key, child }) => {
    return (
      <SubMenu key={key} icon={<UserOutlined />} title={title}>
        {child &&
          child.map((item) => {
            return item.child && item.child.length > 0
              ? this.renderSubMenu(item)
              : this.renderMenu(item);
          })}
      </SubMenu>
    );
  };

  render() {
    return (
      <Fragment>
        <Menu
          mode="inline"
          defaultSelectedKeys={["1"]}
          defaultOpenKeys={["sub1"]}
          style={{ height: "100%", borderRight: 0 }}
          theme="dark"
        >
          {Router &&
            Router.map((firstItem) => {
              return firstItem.child && firstItem.child.length > 0
                ? this.renderSubMenu(firstItem)
                : this.renderMenu(firstItem);
            })}
        </Menu>
      </Fragment>
    );
  }
}

描述:LayoutAside组件中引入AsideMenu组件,AsideMenu组件主要是根据路由文件动态展示导航栏目录,其中renderMenu 、renderSubMenu这两个方法是最关键的,分别对应无子级菜单处理、子级判断处理(递归),然后再render函数中渲染,根据路由文件是否存在子路由来判断显示对应方法。

  • Router 
const router = [
  {
    title: "控制台",
    icon: "home",
    key: "/home",
  },
  {
    title: "用户管理",
    icon: "laptop",
    key: "/home/user",
    child: [
      {
        key: "/home/user/list",
        title: "用户列表",
        icon: "",
      },
      {
        key: "/home/user/add",
        title: "添加用户",
        icon: "",
      },
    ],
  },
  {
    title: "部门管理",
    icon: "bars",
    key: "/home/navigation",
    child: [
      {
        key: "/home/navigation/dropdown",
        title: "部门列表",
        icon: "",
      },
      {
        key: "/home/navigation/menu",
        title: "添加部门",
        icon: "",
        child: [
          {
            key: "/home/navigation/dropdown",
            title: "部门列表",
            icon: "",
          },
          {
            key: "/home/navigation/menu",
            title: "添加部门",
            icon: "",
          },
        ],
      },
    ],
  },
  {
    title: "职位管理",
    icon: "edit",
    key: "/home/entry",
    child: [
      {
        key: "/home/entry/form/basic-form",
        title: "职位列表",
        icon: "",
      },
      {
        key: "/home/entry/form/step-form",
        title: "添加职位",
        icon: "",
      },
    ],
  },
  {
    title: "请假",
    icon: "info-circle-o",
    key: "/home/about1",
  },
  {
    title: "加班",
    icon: "info-circle-o",
    key: "/home/about",
  },
];

export default router;

描述:统一放置路由地址的文件是以这样形式,判断是否有子路由是根据child判断的,所以这边修改要同时修改AsideMenu文件中的child判断。

App.js

import React, { Component } from "react";
import { Switch, Route, BrowserRouter } from "react-router-dom";
import "./app.scss";
// import Home from "./views/Home.js";
import Login from "./views/login/Index";
import Home from "./views/home/Index";
//私有组件
import PrivateRouter from "./components/privateRouter/index";

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <div className="title">
        <BrowserRouter>
          <Switch>
            <Route exact render={() => <Login />} path="/" />
            <PrivateRouter component={Home} path="/home" />
            {/* <Route exact render={() => <Home />} path="/home" /> */}
          </Switch>
        </BrowserRouter>
      </div>
    );
  }
}

描述:这是页面路由的入口文件,放置登录路由、以及首页路由。

结束

  • 目录结构

gitHub地址,欢迎滴滴

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React 路由封装可以通过使用第三方库来实现,最常用的是 React Router。React Router 是一个用于构建单页面应用的路由库,它提供了一些组件和 API,可以让你在 React 应用中实现路由功能。 下面是一个简单的例子,演示如何使用 React Router 进行路由封装: 首先,你需要安装 React Router。在项目根目录下运行以下命令: ``` npm install react-router-dom ``` 然后,在你的应用中导入所需的模块: ```jsx import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; ``` 在你的应用顶层组件中,使用 `<Router>` 组件将整个应用包裹起来: ```jsx function App() { return ( <Router> {/* 这里放置你的其他组件 */} </Router> ); } ``` 接下来,你可以在 `<Router>` 组件内部使用 `<Switch>` 和 `<Route>` 组件来定义路由规则和对应的组件: ```jsx function App() { return ( <Router> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/contact" component={Contact} /> <Route component={NotFound} /> </Switch> </Router> ); } ``` 上述代码中,`<Switch>` 组件会按照定义的顺序依次匹配路由规则,并渲染第一个匹配到的组件。如果都没有匹配到,就会渲染 `<Route>` 组件中定义的 `component` 属性为 `NotFound` 的组件。 最后,你可以在各个对应的组件中使用 React Router 提供的导航组件,如 `<Link>`、`<NavLink>` 等,来实现页面之间的跳转: ```jsx import { Link, NavLink } from 'react-router-dom'; function Navbar() { return ( <nav> <ul> <li><NavLink exact to="/">Home</NavLink></li> <li><NavLink to="/about">About</NavLink></li> <li><NavLink to="/contact">Contact</NavLink></li> </ul> </nav> ); } ``` 以上就是一个简单的 React 路由封装的示例,你可以根据自己的需求进行更高级的路由操作和封装。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值