Layout页面头部和尾部组件
引入NavHeader组件
- src/components/NavHeader/index.tsx
tsx
import {
MenuFoldOutlined,
SmileOutlined,
DownOutlined,
} from "@ant-design/icons";
import { Breadcrumb, Switch, Dropdown, type MenuProps, Space } from "antd";
import { useState } from "react";
import styles from "@/styles/navheader/navheader.module.less";
function NavHeader() {
const [breadlist, setbreadlist] = useState([
{ title: "首页", key: "1" },
{ title: "欢迎页", key: "2" },
]);
const items: MenuProps["items"] = [
{
key: "1",
label: "邮箱:2993222085@qq.com",
},
{
key: "2",
danger: true,
label: "退出登陆",
},
];
return (
<div className={styles.navHeader}>
<div className={styles.left}>
<MenuFoldOutlined />
<Breadcrumb items={breadlist} style={{ marginLeft: 12 }} />
</div>
<div className={styles.right}>
<Switch
checkedChildren="暗黑"
unCheckedChildren="默认"
style={{ marginRight: 12 }}
/>
<Dropdown
menu={{
items,
onClick: ({ key }) => {
console.log(`当前序号:${key},hello world`);
},
}}
trigger={["click"]}
>
<a onClick={(e) => e.preventDefault()}>
<Space className={styles.nickName}>
七宗罪
<DownOutlined />
</Space>
</a>
</Dropdown>
</div>
</div>
);
}
export default NavHeader;- styles/navheader/navheader.module.less
less
.navHeader {
display: flex;
justify-content: space-between;
align-items: center;
height: 64px;
padding: 0 20px;
.left {
display: flex;
align-items: center;
}
.nickName {
cursor: pointer;
color: #000;
}
}- layout/index.tsx
tsx
import { Outlet } from "react-router-dom";
import { Layout, Menu, theme, Watermark } from "antd";
import React from "react";
import styles from "@/styles/layout/layout.module.less";
import NavHeader from "@/components/NavHeader";
const { Header, Content, Footer, Sider } = Layout;
const App: React.FC = () => {
// const {
// token: { colorBgContainer },
// } = theme.useToken();
return (
<Watermark content="七宗罪出品翻版必究">
<Layout>
<Sider
breakpoint="lg"
collapsedWidth="0"
onBreakpoint={(broken) => {
console.log(broken);
}}
onCollapse={(collapsed, type) => {
console.log(collapsed, type);
}}
>
<div className={styles.logo} />
侧边栏
</Sider>
<Layout>
<Header
className={styles["site-layout-sub-header-background"]}
style={{ padding: 0 }}
>
<NavHeader></NavHeader>
</Header>
<Content style={{ margin: "24px 16px 0" }}>
<div
className={styles["site-layout-background"]}
style={{ padding: 24, minHeight: 360 }}
>
<Outlet />
</div>
</Content>
<Footer style={{ textAlign: "center" }}>
Ant Design ©2018 Created by Ant UED
</Footer>
</Layout>
</Layout>
</Watermark>
);
};
export default App;引入NavFooter组件
- src/components/NavFooter/index.tsx
tsx
import styles from "@/styles/navfooter/navfooter.module.less";
import { themeColor } from "@/const/theme";
function NavFooter() {
return (
<div
className={styles.footer}
style={{ "--theme-color": themeColor } as React.CSSProperties}
>
<div>
<a className={styles.link} href="https://www.uiyin.com" target="_blank">
{" "}
个人博客页面
</a>
<span className={styles["gutter"]}>|</span>
<a className={styles.link} href="#" target="_blank">
React后台管理系统
</a>
<span className={styles["gutter"]}>|</span>
<a
className={styles.link}
href="https://demo1.jsopy.com/"
target="_blank"
>
Vue3后台管理系统
</a>
<span className={styles["gutter"]}>|</span>
</div>
<div>Copyright @ 2026 七宗罪React测试项目 All Rights Reserved.</div>
</div>
);
}
export default NavFooter;- 把主题色提取出来 src/const/theme.ts
tsx
const themeColor = "#1D6C0D";
export { themeColor };- styles/navfooter/navfooter.module.less
less
.footer {
text-align: center;
line-height: 30px;
color: #b0aeae;
font-size: 14px;
:global(a) {
color: #78b2f8;
}
.link:hover {
color: var(--theme-color) !important;
}
.gutter {
margin-left: 10px;
margin-right: 10px;
}
}