LayOut页面
增加layout的头部和尾部
增加头部
- components/NavHeader/index.tsx
tsx
import { MenuFoldOutlined, DownOutlined } from "@ant-design/icons";
import { Breadcrumb, Switch, Dropdown, type MenuProps, Space } from "antd";
import { useState } from "react";
import { NavHeaderWrapper, NavLeft, NickName } from "./navheader.css";
function NavHeader() {
const [breadlist] = useState([
{ title: "首页", key: "1" },
{ title: "欢迎页", key: "2" },
]);
const items: MenuProps["items"] = [
{
key: "1",
label: "邮箱:2993222085@qq.com",
},
{
key: "2",
danger: true,
label: "退出登陆",
},
];
return (
<NavHeaderWrapper>
<NavLeft>
<MenuFoldOutlined />
<Breadcrumb items={breadlist} style={{ marginLeft: 12 }} />
</NavLeft>
<div>
<Switch
checkedChildren="暗黑"
unCheckedChildren="默认"
style={{ marginRight: 12 }}
/>
<Dropdown
menu={{
items,
onClick: ({ key }) => {
console.log(`当前序号:${key},hello world`);
},
}}
trigger={["click"]}
>
<a onClick={(e) => e.preventDefault()}>
<NickName>
<Space>
七宗罪
<DownOutlined />
</Space>
</NickName>
</a>
</Dropdown>
</div>
</NavHeaderWrapper>
);
}
export default NavHeader;- components/NavHeader/navheader.css.tsx
tsx
import styled from "@emotion/styled";
export const NavHeaderWrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
height: 64px;
padding: 0 20px;
`;
export const NavLeft = styled.div`
display: flex;
align-items: center;
`;
export const NickName = styled.span`
cursor: pointer;
color: #000;
`;增加尾部
- components/NavFooter/index.tsx
tsx
import { FooterLink, FooterWrapper, Gutter } from "./navfooter.css";
import { themeColor } from "@/constants/theme";
function NavFooter() {
return (
<FooterWrapper
style={{ "--theme-color": themeColor } as React.CSSProperties}
>
<div>
<FooterLink href="https://www.uiyin.com" target="_blank">
个人博客页面
</FooterLink>
<Gutter>|</Gutter>
<FooterLink href="#" target="_blank">
React后台管理系统
</FooterLink>
<Gutter>|</Gutter>
<FooterLink href="https://demo1.jsopy.com/" target="_blank">
Vue3后台管理系统
</FooterLink>
<Gutter>|</Gutter>
</div>
<div>Copyright @ 2026 七宗罪React测试项目 All Rights Reserved.</div>
</FooterWrapper>
);
}
export default NavFooter;- components/NavFooter/navfooter.css.tsx
tsx
import styled from "@emotion/styled";
import { themeColor } from "@/constants/theme";
export const FooterWrapper = styled.div`
text-align: center;
line-height: 30px;
color: #b0aeae;
font-size: 14px;
a {
color: #78b2f8;
}
`;
export const FooterLink = styled.a`
&:hover {
color: ${themeColor} !important;
}
`;
export const Gutter = styled.span`
margin-left: 10px;
margin-right: 10px;
`;constants/theme.tsx
tsx
const themeColor = "#1D6C0D";
export { themeColor };根目录 Layout
- 根目录新建文件夹 layout/index.tsx
tsx
import { Outlet } from "react-router-dom";
import { Layout, Watermark } from "antd";
import React from "react";
import { ContentWrapper, Logo } from "./layout.css";
import NavHeader from "@/components/NavHeader/index";
import NavFooter from "@/components/NavFooter/index";
const { Header, Content, Sider } = Layout;
const App: React.FC = () => {
return (
<Watermark content="翻版必究">
<Layout style={{ minHeight: "100vh" }}>
<Sider
breakpoint="lg"
collapsedWidth="0"
onBreakpoint={(broken) => {
console.log(broken);
}}
onCollapse={(collapsed, type) => {
console.log(collapsed, type);
}}
>
<Logo>ReactCMS</Logo>
</Sider>
<Layout>
<Header style={{ padding: 0, background: "#fff" }}>
<NavHeader></NavHeader>
</Header>
<Content style={{ margin: "24px 16px 0" }}>
<ContentWrapper style={{ padding: 24, minHeight: 360 }}>
<Outlet />
</ContentWrapper>
</Content>
<NavFooter></NavFooter>
</Layout>
</Layout>
</Watermark>
);
};
export default App;- layouts/layout.css.tsx
tsx
import styled from "@emotion/styled";
export const Logo = styled.div`
height: 32px;
margin: 16px;
background: rgba(255, 255, 255, 0.2);
color: #fff;
line-height: 32px;
text-align: center;
`;
export const SubHeader = styled.div`
background: #fff;
`;
export const ContentWrapper = styled.div`
background: #fff;
`;