React+TS前台项目实战(四)-- layout整体布局搭建


前言

本文主要讲Layout整体布局的构建以及全局内容盒子Content组件的使用。还包括了导航栏组件的基本封装,并将在后续内容中单独讲解头部header组件的响应式设计,特别是针对移动端的布局要求,以及涉及的交互。


一、Layout组件代码+注释说明

// @/layout/index.tsx
import { useEffect, Suspense } from "react";
import { useParams, Outlet, Navigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
// 引用组件
import { ErrorBoundary } from "@/components/ErrorBoundary";
import Header from "@/components/Header";
import Footer from "@/components/Footer";
import Content from "@/components/Content";
// 引用样式
import { Page } from "./styled";
const LayOut = () => {
    return (
      <Page>
        <Header /> {/* 头部组件 */}
        <Suspense fallback={<span>loading...</span>}>
          <ErrorBoundary> 
            <Content> {/* 全局盒子组件 */}
              <Outlet />
            </Content>
          </ErrorBoundary>
        </Suspense>
        <Footer /> {/* 头部组件 */}
      </Page>
    );
};
export default LayOut;
---------------------------------------------------------------------------------
// @/layout/styled.tsx
import styled from "styled-components";
export const Page = styled.div`
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  box-sizing: border-box;
  background-color: #ffffff;
  position: relative;

二、Content全局组件+注释说明

// @/components/content.tsx
import { CSSProperties, ReactNode } from "react";
import { Content } from "./styled";
interface ContentProps = { children: ReactNode; style?: CSSProperties }
export default ({ children, style }: ContentProps) => {
  return <Content style={style}>{children}</Content>;
};
-------------------------------------------------------------------------------------
// @/components/styled.tsx
import styled from "styled-components";
export const Content = styled.div`
  width: 100%;
  flex: 1;
  background: #ffffff;
`;

三、Header基础布局组件

注:组件全部功能及响应式移动端后面会单独讲

1. Header父级组件+注释说明

// @/components/header/index.tsx
import { FC, useEffect, useState } from "react";
import { useLocation } from "react-router";
import { useTranslation } from "react-i18next";
import classNames from "classnames";
import LogoIcon from "@/assets/logo.png";
import { Header, Logo } from "./styled";
import styles from "./index.module.scss";
import Modal from "@/pages/components/commonDialog";
import NavMenu from "./NavMenu";

export default () => {
  const { pathname } = useLocation();
  return (
    <div className={styles.headerContainer}>
      <Header>
        <Logo to="/">
          <img src={LogoIcon} alt="logo" />
        </Logo>
        <NavMenu /> {/* 导航组件 */}
      </Header>
    </div>
  );
};
-----------------------------------------------------------------------------
// @/components/header/styled.tsx
import styled from "styled-components";
import Link from "../Link";
export const Header = styled.div`
  width: 100%;
  min-height: var(--cd-navbar-height);
  background-color: #1898fc;
  overflow: visible;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  padding: 0 120px;

  @media (max-width: 1440px) {
    padding: 0 100px;
  }

  @media (max-width: 1200px) {
    padding: 0 40px;
  }

  @media (max-width: 780px) {
    padding: 0 16px;
  }
-----------------------------------------------------------------------------
// @/components/header/index.module.scss
.headerContainer {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;

  &.expand {
    height: 100vh;
  }
}

2. NavMenu导航子组件+详细说明

// @/components/header/Navmenu/index.tsx
import { FC, useEffect, useState } from "react";
import { useLocation } from "react-router";
import { useTranslation } from "react-i18next";
import styles from "./index.module.scss";
import Link from "@/components/Link";

interface navListMap {
  name: string;
  url: string;
}
const useNavList = () => {
  const { t } = useTranslation();
  const list: navListMap[] = [
    {
      name: t("navbar.home"),
      url: "/home",
    },
    {
      name: t("navbar.nervos_dao"),
      url: "/nervosdao",
    },
    {
      name: t("navbar.tokens"),
      url: "/tokens",
    },
    {
      name: t("navbar.fee_rate"),
      url: "/fee-rate-tracker",
    },
    {
      name: t("navbar.charts"),
      url: "/charts",
    },
  ];
  return list;
};
export default () => {
  const navList = useNavList();
  return (
    <div className={styles.navContent}>
      {navList.map((item) => (
        <Link className={styles.navItem} to={item.url ?? "/"} key={item.name}>
          {item.name}
        </Link>
      ))}
    </div>
  );
};
-----------------------------------------------------------------------------
// @/components/header/Navmenu/index.modulex.scss
.navContent {
  display: flex;
  flex: 1;
  min-width: 0;
  .navItem {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    margin-right: 50px;
    color: white;
    &:hover {
      color: var(--cd-primary-color);
    }
  }
}

四、效果展示

在这里插入图片描述


总结

下一篇讲【全局常用组件封装】。关注本栏目,将实时更新。

相关推荐

  1. 仿美团H5项目实战系列- 项目整体框架

    2024-06-10 11:06:03       17 阅读
  2. react+umi+antd项目配置

    2024-06-10 11:06:03       41 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-10 11:06:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-10 11:06:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-10 11:06:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-10 11:06:03       20 阅读

热门阅读

  1. React@16.x(24)自定义HOOK

    2024-06-10 11:06:03       13 阅读
  2. 近邻算法详解

    2024-06-10 11:06:03       10 阅读
  3. 5_1 Linux 计划任务

    2024-06-10 11:06:03       9 阅读
  4. linux install cmake3.22

    2024-06-10 11:06:03       9 阅读
  5. 文心一言使用技巧

    2024-06-10 11:06:03       10 阅读
  6. 前端三大主流框架:React、Vue、Angular

    2024-06-10 11:06:03       9 阅读