「Offer 驾到,掘友接招!我正在参与2022春招系列活动-项目经验复盘,点击查看 征文活动详情。
创建
执行命令yarn create @umijs/umi-app
通过官方工具创建项目,安装依赖,启动项目。
浏览器 http://localhost:8000/
页面就是如此简单。
先来看一下我们实现的效果图
可以说是非常符合管理系统的样子。
关于 umi 的基础知识,这里就不做过多的介绍了。相关的知识点,网上应该都是可以搜索到的。
路由部分
src/routes.ts
,导出 router 对象。
import {
HddOutlined,
HourglassOutlined,
ApartmentOutlined,
} from "@ant-design/icons";
export const routesMaps = [
{
name: "page1",
path: "/page1/view1",
label: "页面一",
Icon: ApartmentOutlined,
children: [
{
name: "page1-children",
path: "/page1/view1/list",
component: "@/pages/Page_one/List",
label: "子页面",
exact: true,
},
],
},
{
name: "page1-list-redirect",
path: "/page1/list",
component: "@/pages/Page_one/List",
label: "个人工作台-重定向",
exact: true,
redirect: "/page1/list",
menu: false,
},
{
name: "page1-detail",
path: "/page666/detail/:id/:type/:state",
component: "@/pages/Page_one/Detail",
label: "页面详情",
menu: false,
},
{
name: "page2",
path: "/page2/view2",
label: "页面二",
Icon: HddOutlined,
children: [
{
name: "page2-list",
path: "/page2/view2/list",
component: "@/pages/Page_two/List",
label: "子页面",
exact: true,
},
{
name: "page2-panel",
path: "/page2/view2/list2",
component: "@/pages/Page_two/Panel",
label: "另外一个子页面",
exact: true,
},
{
name: "Page_two-detail",
path: "/page2/view2/detail/:id/:type/:state",
component: "@/pages/Page_two/Detail",
label: "没有出现在 menu 中的详情页面",
menu: false,
},
],
},
{
name: "page3",
path: "/page3/view1",
label: "页面三",
Icon: HourglassOutlined,
children: [
{
name: "page3-list",
path: "/page3/view1/list",
component: "@/pages/Page_three/List",
label: "子页面",
exact: true,
},
{
name: "page3-vvvvv",
path: "/page3/view1/:id/:type/:state",
component: "@/pages/Page_three/Detail",
label: "没有出现在 menu 中的子页面",
menu: false,
},
],
},
{
name: "page10",
path: "/page10/view10/:id/:type/:state",
component: "@/pages/Page_four/Detail",
label: "没有出现在 menu 中的子页面",
menu: false,
}
];
exact: true
需要校验的页面redirect: "/page1/list"
重定向页面menu: false
不显示在侧边栏
重设浏览器的样式
最简单的初始化方法就是: * {margin: 0;padding: 0; }
。这样写确实很快,但如果网站很大、CSS样式表文件很大的时候,用*号这样一个通用符来写初始化样式,浏览器会把所有的标签都初始化一遍,这样就大大地加强了网站运行的负载,会使网站加载的时候需要很长一段时间。
src/global.less
@import "~antd/lib/style/themes/default.less";
@import "~antd/dist/antd.less";
/* css reset code */
body {
font-size: 62.5%;
}
html>body {
font-size: 10px;
}
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
form,
fieldset,
input,
textarea,
p,
blockquote,
th,
td {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
address,
caption,
cite,
code,
dfn,
th,
var {
font-weight: normal;
font-style: normal;
}
ol,
ul {
list-style: none;
}
caption,
th {
text-align: left;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: normal;
font-size: 100%;
}
q:before,
q:after {
content: "";
}
abbr,
acronym {
border: 0;
}
a {
text-decoration: none;
}
.ml-10 {
margin-left: 10px;
}
.ant-form-item-explain {
margin-top: 0;
}
.ant-form .ant-picker-range {
width: 100%;
}
侧边导航栏
src/layouts/index.tsx
import React from 'react';
import type { history as umiHistory } from 'umi';
import { Layout, ConfigProvider } from 'antd';
import zh_CN from 'antd/es/locale/zh_CN';
import Menu from './Menu';
import './index.less';
const isInIframe = window.top !== window.self;
interface MenuProps {
history: typeof umiHistory;
children: React.ReactNode;
}
export default (props: MenuProps) => {
const { children, history } = props;
return (
<ConfigProvider locale={zh_CN}>
<Layout className="x-layout">
{isInIframe ? null : <Menu history={history} />}
<Layout className="x-layout-main">{children}</Layout>
</Layout>
</ConfigProvider>
);
};
<Menu history={history} />
沿用 Antd 的经典布局
<Sider
trigger={null}
collapsible
collapsed={false}
className="example-sider"
>
<Row justify="center" align="middle" className="header-wrapper">
<span className="main-title"></span>
</Row>
<Menu
pathname={history.location.pathname}
routesMaps={routesMaps}
onClick={handlerClick}
mode="inline"
theme="dark"
/>
</Sider>
Menu
是基于 Antd Menu
二次封装的。
页面上方的上下班状态使用 Antd 的 Switch 进行控制。
主要的接口还是需要看具体的业务。
<div className="example">
<Row className="example-header" align="middle" justify="end">
{isTeamMember && (
<Switch
checkedChildren="上班"
unCheckedChildren="下班"
checked={workStatus}
onChange={handleWorkStatusChange}
className="switch"
/>
)}
<Text style={{ fontSize: 13 }}>Hi,{userNameZh}</Text>
</Row>
<div className="content-area">{children}</div>
</div>
我想想还有什么没说的,
其实封装还是需要根据自身的业务情况来执行,
不过,我将自己在项目中的实践抽离出来,
上方展示的项目代码我放在了 gitee.com/suiboyu/umi… 仓库中。
各位 git clone,安装依赖之后,尝试运行起来。
项目中也有示例代码。