添加布局组件
- 创建主布局框架(Header、Footer、MainLayout) - 实现导航菜单和用户入口 - 添加响应式设计支持
This commit is contained in:
parent
f7a1c8b580
commit
b4947b89e1
206
src/layout/Footer.css
Normal file
206
src/layout/Footer.css
Normal file
@ -0,0 +1,206 @@
|
||||
/* 非遗文化传承网站 - Footer 样式 */
|
||||
|
||||
.heritage-footer {
|
||||
background-color: #2c2c2c;
|
||||
color: #ffffff;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
padding: 60px 0 40px;
|
||||
}
|
||||
|
||||
.footer-container {
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
padding: 0 50px;
|
||||
}
|
||||
|
||||
/* Footer Section */
|
||||
.footer-section {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.footer-title {
|
||||
color: #ffffff !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
margin-bottom: 20px !important;
|
||||
font-family: 'Noto Serif SC', 'Songti SC', serif;
|
||||
}
|
||||
|
||||
.footer-description {
|
||||
color: #cccccc !important;
|
||||
font-size: 13px;
|
||||
line-height: 1.8;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
/* 社交媒体链接 */
|
||||
.footer-social {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.social-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
color: #ffffff;
|
||||
font-size: 18px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.social-link:hover {
|
||||
background-color: #c8363d;
|
||||
color: #ffffff;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Footer 链接 */
|
||||
.footer-links {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer-links li {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
color: #cccccc;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: #d4a574;
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
/* 联系信息 */
|
||||
.footer-contact {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
color: #cccccc;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.contact-icon {
|
||||
color: #d4a574;
|
||||
font-size: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.contact-item .ant-typography {
|
||||
color: #cccccc;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 分割线 */
|
||||
.footer-divider {
|
||||
border-top-color: rgba(255, 255, 255, 0.1);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 底部版权区 */
|
||||
.footer-bottom {
|
||||
padding: 24px 0;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.footer-copyright {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.copyright-text {
|
||||
color: #999999 !important;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.footer-legal {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.footer-legal a {
|
||||
color: #999999;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-legal a:hover {
|
||||
color: #d4a574;
|
||||
}
|
||||
|
||||
.footer-legal .ant-divider-vertical {
|
||||
border-left-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 992px) {
|
||||
.footer-container {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
padding: 48px 0 32px;
|
||||
}
|
||||
|
||||
.footer-copyright {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.footer-container {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
padding: 40px 0 24px;
|
||||
}
|
||||
|
||||
.footer-title {
|
||||
font-size: 15px !important;
|
||||
margin-bottom: 16px !important;
|
||||
}
|
||||
|
||||
.footer-description {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footer-links a,
|
||||
.contact-item .ant-typography {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.copyright-text,
|
||||
.footer-legal a {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
154
src/layout/Footer.tsx
Normal file
154
src/layout/Footer.tsx
Normal file
@ -0,0 +1,154 @@
|
||||
/**
|
||||
* 非遗文化传承网站 - 页脚组件
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Row, Col, Space, Typography, Divider } from 'antd'
|
||||
import {
|
||||
WechatOutlined,
|
||||
WeiboOutlined,
|
||||
MailOutlined,
|
||||
PhoneOutlined,
|
||||
EnvironmentOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import './Footer.css'
|
||||
|
||||
const { Title, Text, Paragraph } = Typography
|
||||
|
||||
const Footer: React.FC = () => {
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
return (
|
||||
<footer className="heritage-footer">
|
||||
<div className="footer-main">
|
||||
<div className="footer-container">
|
||||
<Row gutter={[48, 32]}>
|
||||
{/* 关于我们 */}
|
||||
<Col xs={24} sm={12} lg={6}>
|
||||
<div className="footer-section">
|
||||
<Title level={5} className="footer-title">
|
||||
非遗传承
|
||||
</Title>
|
||||
<Paragraph className="footer-description">
|
||||
让千年技艺重焕新生,用数字科技守护文化根脉。
|
||||
致力于中国非物质文化遗产的数字化保护、传承与推广。
|
||||
</Paragraph>
|
||||
<Space size="middle" className="footer-social">
|
||||
<a href="#" className="social-link">
|
||||
<WechatOutlined />
|
||||
</a>
|
||||
<a href="#" className="social-link">
|
||||
<WeiboOutlined />
|
||||
</a>
|
||||
<a href="#" className="social-link">
|
||||
<MailOutlined />
|
||||
</a>
|
||||
</Space>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
{/* 快速链接 */}
|
||||
<Col xs={12} sm={12} lg={6}>
|
||||
<div className="footer-section">
|
||||
<Title level={5} className="footer-title">
|
||||
快速链接
|
||||
</Title>
|
||||
<ul className="footer-links">
|
||||
<li>
|
||||
<Link to="/heritage">非遗项目</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/inheritors">传承人</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/news">活动资讯</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/data">数据可视化</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/about">关于我们</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
{/* 项目分类 */}
|
||||
<Col xs={12} sm={12} lg={6}>
|
||||
<div className="footer-section">
|
||||
<Title level={5} className="footer-title">
|
||||
非遗分类
|
||||
</Title>
|
||||
<ul className="footer-links">
|
||||
<li>
|
||||
<Link to="/heritage/categories/traditional-craft">传统技艺</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/heritage/categories/traditional-art">传统美术</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/heritage/categories/traditional-music">传统音乐</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/heritage/categories/traditional-opera">传统戏剧</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/heritage/categories/folk-custom">民俗</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/heritage/categories/traditional-medicine">传统医药</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
{/* 联系我们 */}
|
||||
<Col xs={24} sm={12} lg={6}>
|
||||
<div className="footer-section">
|
||||
<Title level={5} className="footer-title">
|
||||
联系我们
|
||||
</Title>
|
||||
<Space direction="vertical" size="middle" className="footer-contact">
|
||||
<div className="contact-item">
|
||||
<PhoneOutlined className="contact-icon" />
|
||||
<Text>400-123-4567</Text>
|
||||
</div>
|
||||
<div className="contact-item">
|
||||
<MailOutlined className="contact-icon" />
|
||||
<Text>heritage@example.com</Text>
|
||||
</div>
|
||||
<div className="contact-item">
|
||||
<EnvironmentOutlined className="contact-icon" />
|
||||
<Text>北京市朝阳区文化创意产业园</Text>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 版权信息 */}
|
||||
<Divider className="footer-divider" />
|
||||
<div className="footer-bottom">
|
||||
<div className="footer-container">
|
||||
<div className="footer-copyright">
|
||||
<Text className="copyright-text">
|
||||
© {currentYear} 非遗文化传承平台. All Rights Reserved.
|
||||
</Text>
|
||||
<Space split={<Divider type="vertical" />} className="footer-legal">
|
||||
<Link to="/privacy">隐私政策</Link>
|
||||
<Link to="/terms">服务条款</Link>
|
||||
<a href="https://beian.miit.gov.cn" target="_blank" rel="noopener noreferrer">
|
||||
京ICP备xxxxxxxx号
|
||||
</a>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
||||
169
src/layout/Header.css
Normal file
169
src/layout/Header.css
Normal file
@ -0,0 +1,169 @@
|
||||
/* 非遗文化传承网站 - Header 样式 */
|
||||
|
||||
.heritage-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.heritage-header.scrolled {
|
||||
background-color: rgba(255, 255, 255, 0.98);
|
||||
border-bottom-color: #e8e3db;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.header-container {
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
padding: 0 50px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Logo 样式 */
|
||||
.header-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
text-decoration: none;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.header-logo:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(135deg, #c8363d 0%, #8b252b 100%);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
font-family: 'Noto Serif SC', 'Songti SC', serif;
|
||||
box-shadow: 0 2px 8px rgba(200, 54, 61, 0.3);
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.logo-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2c2c2c;
|
||||
line-height: 1.2;
|
||||
font-family: 'Noto Serif SC', 'Songti SC', serif;
|
||||
}
|
||||
|
||||
.logo-subtitle {
|
||||
font-size: 11px;
|
||||
color: #999999;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* 导航菜单样式 */
|
||||
.header-nav {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.header-menu {
|
||||
border-bottom: none;
|
||||
background: transparent;
|
||||
min-width: 600px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.header-menu .ant-menu-item,
|
||||
.header-menu .ant-menu-submenu {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
margin: 0 4px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.header-menu .ant-menu-item a,
|
||||
.header-menu .ant-menu-submenu-title {
|
||||
color: #666666;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.header-menu .ant-menu-item:hover a,
|
||||
.header-menu .ant-menu-submenu:hover .ant-menu-submenu-title {
|
||||
color: #c8363d;
|
||||
}
|
||||
|
||||
.header-menu .ant-menu-item-selected a {
|
||||
color: #c8363d;
|
||||
}
|
||||
|
||||
/* 移动端菜单按钮 */
|
||||
.mobile-menu-btn {
|
||||
display: none;
|
||||
font-size: 20px;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
/* 移动端抽屉样式 */
|
||||
.mobile-menu-drawer .ant-drawer-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mobile-menu-drawer .ant-menu {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 992px) {
|
||||
.header-container {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.desktop-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-menu-btn {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.header-container {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.logo-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.logo-subtitle {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
140
src/layout/Header.tsx
Normal file
140
src/layout/Header.tsx
Normal file
@ -0,0 +1,140 @@
|
||||
/**
|
||||
* 非遗文化传承网站 - 头部导航组件
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { Menu, Drawer, Button, Space } from 'antd'
|
||||
import {
|
||||
MenuOutlined,
|
||||
HomeOutlined,
|
||||
AppstoreOutlined,
|
||||
TeamOutlined,
|
||||
ExperimentOutlined,
|
||||
FileTextOutlined,
|
||||
InfoCircleOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import type { MenuProps } from 'antd'
|
||||
import './Header.css'
|
||||
|
||||
type MenuItem = Required<MenuProps>['items'][number]
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const location = useLocation()
|
||||
const [scrolled, setScrolled] = useState(false)
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
||||
|
||||
// 监听滚动事件,添加导航栏背景效果
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setScrolled(window.scrollY > 50)
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => window.removeEventListener('scroll', handleScroll)
|
||||
}, [])
|
||||
|
||||
// 导航菜单项
|
||||
const menuItems: MenuItem[] = [
|
||||
{
|
||||
key: '/',
|
||||
icon: <HomeOutlined />,
|
||||
label: <Link to="/">首页</Link>,
|
||||
},
|
||||
{
|
||||
key: '/heritage',
|
||||
icon: <AppstoreOutlined />,
|
||||
label: <Link to="/heritage">非遗项目</Link>,
|
||||
},
|
||||
{
|
||||
key: '/inheritors',
|
||||
icon: <TeamOutlined />,
|
||||
label: <Link to="/inheritors">传承人</Link>,
|
||||
},
|
||||
{
|
||||
key: '/news',
|
||||
icon: <FileTextOutlined />,
|
||||
label: <Link to="/news">活动资讯</Link>,
|
||||
},
|
||||
{
|
||||
key: '/about',
|
||||
icon: <InfoCircleOutlined />,
|
||||
label: <Link to="/about">关于我们</Link>,
|
||||
},
|
||||
]
|
||||
|
||||
// 获取当前选中的菜单项
|
||||
const getSelectedKeys = () => {
|
||||
const path = location.pathname
|
||||
// 精确匹配或父级匹配
|
||||
if (path === '/') return ['/']
|
||||
if (path.startsWith('/heritage')) {
|
||||
const categoryMatch = path.match(/\/heritage\/categories\/(.+)/)
|
||||
if (categoryMatch) {
|
||||
return [`/heritage/${categoryMatch[1]}`]
|
||||
}
|
||||
return ['/heritage']
|
||||
}
|
||||
if (path.startsWith('/inheritors')) return ['/inheritors']
|
||||
if (path.startsWith('/learn')) return ['/learn']
|
||||
if (path.startsWith('/news')) return ['/news']
|
||||
if (path.startsWith('/about')) return ['/about']
|
||||
if (path.startsWith('/data')) return ['/data']
|
||||
if (path.startsWith('/search')) return ['/search']
|
||||
if (path.startsWith('/user')) return ['/user']
|
||||
return []
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className={`heritage-header ${scrolled ? 'scrolled' : ''}`}>
|
||||
<div className="header-container">
|
||||
{/* Logo */}
|
||||
<Link to="/" className="header-logo">
|
||||
<div className="logo-icon">非遗</div>
|
||||
<div className="logo-text">
|
||||
<div className="logo-title">非遗传承</div>
|
||||
<div className="logo-subtitle">Heritage</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* 桌面导航菜单 */}
|
||||
<nav className="header-nav desktop-nav">
|
||||
<Menu
|
||||
mode="horizontal"
|
||||
selectedKeys={getSelectedKeys()}
|
||||
items={menuItems}
|
||||
className="header-menu"
|
||||
/>
|
||||
</nav>
|
||||
|
||||
{/* 移动端菜单按钮 */}
|
||||
<Button
|
||||
type="text"
|
||||
icon={<MenuOutlined />}
|
||||
className="mobile-menu-btn"
|
||||
onClick={() => setMobileMenuOpen(true)}
|
||||
/>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* 移动端抽屉菜单 */}
|
||||
<Drawer
|
||||
title="导航菜单"
|
||||
placement="right"
|
||||
onClose={() => setMobileMenuOpen(false)}
|
||||
open={mobileMenuOpen}
|
||||
className="mobile-menu-drawer"
|
||||
>
|
||||
<Menu
|
||||
mode="inline"
|
||||
selectedKeys={getSelectedKeys()}
|
||||
items={menuItems}
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
/>
|
||||
</Drawer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
||||
71
src/layout/MainLayout.css
Normal file
71
src/layout/MainLayout.css
Normal file
@ -0,0 +1,71 @@
|
||||
/* 非遗文化传承网站 - MainLayout 样式 */
|
||||
|
||||
.main-layout {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fafaf8;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
margin-top: 64px; /* Header 高度 */
|
||||
min-height: calc(100vh - 64px);
|
||||
}
|
||||
|
||||
/* 返回顶部按钮样式 */
|
||||
.back-to-top {
|
||||
right: 40px;
|
||||
bottom: 40px;
|
||||
}
|
||||
|
||||
.back-to-top-button {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #c8363d 0%, #8b252b 100%);
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
box-shadow: 0 4px 16px rgba(200, 54, 61, 0.3);
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.back-to-top-button:hover {
|
||||
transform: scale(1.1) translateY(-2px);
|
||||
box-shadow: 0 6px 24px rgba(200, 54, 61, 0.4);
|
||||
}
|
||||
|
||||
.back-to-top-button:active {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.back-to-top {
|
||||
right: 24px;
|
||||
bottom: 24px;
|
||||
}
|
||||
|
||||
.back-to-top-button {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.back-to-top {
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
}
|
||||
|
||||
.back-to-top-button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
39
src/layout/MainLayout.tsx
Normal file
39
src/layout/MainLayout.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 非遗文化传承网站 - 主布局组件
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import { Outlet } from 'react-router-dom'
|
||||
import { Layout, BackTop } from 'antd'
|
||||
import { UpOutlined } from '@ant-design/icons'
|
||||
import Header from './Header'
|
||||
import Footer from './Footer'
|
||||
import './MainLayout.css'
|
||||
|
||||
const { Content } = Layout
|
||||
|
||||
const MainLayout: React.FC = () => {
|
||||
return (
|
||||
<Layout className="main-layout">
|
||||
{/* 头部导航 */}
|
||||
<Header />
|
||||
|
||||
{/* 主内容区 */}
|
||||
<Content className="main-content">
|
||||
<Outlet />
|
||||
</Content>
|
||||
|
||||
{/* 页脚 */}
|
||||
<Footer />
|
||||
|
||||
{/* 返回顶部按钮 */}
|
||||
<BackTop className="back-to-top">
|
||||
<div className="back-to-top-button">
|
||||
<UpOutlined />
|
||||
</div>
|
||||
</BackTop>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default MainLayout
|
||||
Loading…
Reference in New Issue
Block a user