feat: 重构布局为上侧右结构,集成 antd 全局配置与中文语言
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^6.2.3",
|
"@ant-design/icons": "^6.2.3",
|
||||||
"antd": "^6.4.2",
|
"antd": "^6.4.2",
|
||||||
|
"dayjs": "^1.11.20",
|
||||||
"react": "^19.2.6",
|
"react": "^19.2.6",
|
||||||
"react-dom": "^19.2.6",
|
"react-dom": "^19.2.6",
|
||||||
"react-router": "^7.15.1"
|
"react-router": "^7.15.1"
|
||||||
|
|||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -14,6 +14,9 @@ importers:
|
|||||||
antd:
|
antd:
|
||||||
specifier: ^6.4.2
|
specifier: ^6.4.2
|
||||||
version: 6.4.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
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:
|
react:
|
||||||
specifier: ^19.2.6
|
specifier: ^19.2.6
|
||||||
version: 19.2.6
|
version: 19.2.6
|
||||||
|
|||||||
27
src/App.css
27
src/App.css
@@ -1,26 +1,9 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #fff;
|
padding: 0;
|
||||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
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 { RouterProvider } from 'react-router';
|
||||||
import router from './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;
|
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 RootLayout = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Layout style={{ height: '100vh' }}>
|
||||||
<nav>
|
<Header
|
||||||
<Link to="/">首页</Link>
|
style={{
|
||||||
{' | '}
|
display: 'flex',
|
||||||
<Link to="/about">关于</Link>
|
alignItems: 'center',
|
||||||
</nav>
|
padding: '0 24px',
|
||||||
<main>
|
background: '#fff',
|
||||||
<Outlet />
|
borderBottom: '1px solid #f0f0f0',
|
||||||
</main>
|
}}
|
||||||
</>
|
>
|
||||||
|
<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 About from '../pages/About';
|
||||||
import Home from '../pages/Home';
|
import Home from '../pages/Home';
|
||||||
import NotFound from '../pages/NotFound';
|
import NotFound from '../pages/NotFound';
|
||||||
@@ -7,11 +8,13 @@ export const routes: RouteItem[] = [
|
|||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
label: '首页',
|
label: '首页',
|
||||||
|
icon: <HomeOutlined />,
|
||||||
component: <Home />,
|
component: <Home />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/about',
|
path: '/about',
|
||||||
label: '关于',
|
label: '关于',
|
||||||
|
icon: <InfoCircleOutlined />,
|
||||||
component: <About />,
|
component: <About />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user