feat: 重构布局为上侧右结构,集成 antd 全局配置与中文语言
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.2.3",
|
||||
"antd": "^6.4.2",
|
||||
"dayjs": "^1.11.20",
|
||||
"react": "^19.2.6",
|
||||
"react-dom": "^19.2.6",
|
||||
"react-router": "^7.15.1"
|
||||
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -14,6 +14,9 @@ importers:
|
||||
antd:
|
||||
specifier: ^6.4.2
|
||||
version: 6.4.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
dayjs:
|
||||
specifier: ^1.11.20
|
||||
version: 1.11.20
|
||||
react:
|
||||
specifier: ^19.2.6
|
||||
version: 19.2.6
|
||||
|
||||
27
src/App.css
27
src/App.css
@@ -1,26 +1,9 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
color: #fff;
|
||||
padding: 0;
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
background-image: linear-gradient(to bottom, #020917, #101725);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
line-height: 1.1;
|
||||
text-align: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.content h1 {
|
||||
font-size: 3.6rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.content p {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 400;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
15
src/App.tsx
15
src/App.tsx
@@ -1,6 +1,19 @@
|
||||
import { App as AntdApp, ConfigProvider } from 'antd';
|
||||
import zhCN from 'antd/locale/zh_CN';
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/zh-cn';
|
||||
import { RouterProvider } from 'react-router';
|
||||
import router from './router';
|
||||
import './App.css';
|
||||
|
||||
const App = () => <RouterProvider router={router} />;
|
||||
dayjs.locale('zh-cn');
|
||||
|
||||
const App = () => (
|
||||
<ConfigProvider locale={zhCN}>
|
||||
<AntdApp>
|
||||
<RouterProvider router={router} />
|
||||
</AntdApp>
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -1,17 +1,86 @@
|
||||
import { Link, Outlet } from 'react-router';
|
||||
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
|
||||
import { Layout, Menu } from 'antd';
|
||||
import { useState } from 'react';
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router';
|
||||
import { routes } from '../routes';
|
||||
|
||||
const { Header, Sider, Content } = Layout;
|
||||
|
||||
const menuItems = routes
|
||||
.filter((r) => !r.hideInMenu)
|
||||
.map((r) => ({
|
||||
key: r.path,
|
||||
icon: r.icon,
|
||||
label: r.label,
|
||||
}));
|
||||
|
||||
const RootLayout = () => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav>
|
||||
<Link to="/">首页</Link>
|
||||
{' | '}
|
||||
<Link to="/about">关于</Link>
|
||||
</nav>
|
||||
<main>
|
||||
<Outlet />
|
||||
</main>
|
||||
</>
|
||||
<Layout style={{ height: '100vh' }}>
|
||||
<Header
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '0 24px',
|
||||
background: '#fff',
|
||||
borderBottom: '1px solid #f0f0f0',
|
||||
}}
|
||||
>
|
||||
<span style={{ fontWeight: 'bold', fontSize: 18 }}>TaoTie</span>
|
||||
</Header>
|
||||
<Layout style={{ overflow: 'hidden' }}>
|
||||
<Sider
|
||||
theme="light"
|
||||
width={200}
|
||||
collapsed={collapsed}
|
||||
style={{ borderRight: '1px solid #f0f0f0', position: 'relative' }}
|
||||
>
|
||||
<Menu
|
||||
mode="inline"
|
||||
selectedKeys={[location.pathname]}
|
||||
items={menuItems}
|
||||
onClick={({ key }) => navigate(key)}
|
||||
style={{ height: '100%', borderRight: 0, paddingBottom: 48 }}
|
||||
/>
|
||||
<div
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 48,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: collapsed ? 'center' : 'flex-end',
|
||||
padding: collapsed ? 0 : '0 24px',
|
||||
borderTop: '1px solid #f0f0f0',
|
||||
cursor: 'pointer',
|
||||
color: '#666',
|
||||
background: '#fff',
|
||||
transition: 'all 0.2s',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
{collapsed ? (
|
||||
<MenuUnfoldOutlined />
|
||||
) : (
|
||||
<>
|
||||
<MenuFoldOutlined style={{ marginRight: 8 }} />
|
||||
<span style={{ fontSize: 13 }}>收起</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Sider>
|
||||
<Content style={{ padding: 0, overflow: 'auto' }}>
|
||||
<Outlet />
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { HomeOutlined, InfoCircleOutlined } from '@ant-design/icons';
|
||||
import About from '../pages/About';
|
||||
import Home from '../pages/Home';
|
||||
import NotFound from '../pages/NotFound';
|
||||
@@ -7,11 +8,13 @@ export const routes: RouteItem[] = [
|
||||
{
|
||||
path: '/',
|
||||
label: '首页',
|
||||
icon: <HomeOutlined />,
|
||||
component: <Home />,
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
label: '关于',
|
||||
icon: <InfoCircleOutlined />,
|
||||
component: <About />,
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user