React入门第一章:了解Ant Design Pro基础框架

2,499 阅读8分钟

我个人喜欢从实战入手框架,在对react文档功能有了基本的了解以后,使用ant-design-pro直接上手熟悉react的功能。

相关版本:
react 17.0.0
ant-design 4.14.0
ant-design-pro 5.0.0

安装ant-design-pro并熟悉项目结构

首先通过脚手架下载Ant Design Pro
然后将项目启动,根据本地项目结构参考Ant Design Pro 文件夹结构了解每个文件夹的作用。

根据Ant Design Pro的文档安装模板。

1.1 安装ant-design-pro

# 初始化脚手架
$ yarn create umi myapp

# 选择 ant-design-pro
? Select the boilerplate type (Use arrow keys)
❯ ant-design-pro  - Create project with a layout-only ant-design-pro boilerplate
, use together with umi block.
  app             - Create project with a simple boilerplate, support typescript
.
  plugin          - Create a umi plugin.

# 选择开发语言(TypeScript)
? 🤓 Which language do you want to use? (Use arrow keys)
  TypeScript
❯ JavaScript

# simple 是基础模板, complete 包含 antd 的集成方案(simple)
? 🚀 Do you need all the blocks or a simple scaffold? (Use arrow keys)
❯ simple
  complete

# 安装依赖
$ cd myapp && yarn

# 启动项目
yarn start

1.2 重要的文件目录

熟悉的配方,熟悉的结构。

config umi 配置,包含路由,构建等配置
mock 本地模拟数据
src 源码目录

基于Webpack的项目基本都是上述三个目录,配置工程、本地数据模拟、项目源码。 其他的文件都是本地工程用到的描述或配置文件,根据自己需求改动。

修改系统配置,删减无用内容

虽然安装了Ant Design Pro模板版本,但是它还是会内置一些东西,需要将其删除

修改系统全局设置

模板默认的配色及结构和预期不一致,需要修改配置调整为常规方案。文件位置 config/defaulltSetting.ts 此处需要打开ant-design-pro预览网站,通过右侧配置,将UI调整为目标样子后复制设置到自己的项目中。

export default {
  "navTheme": "dark",
  "primaryColor": "#1890ff",
  "layout": "side",
  "contentWidth": "Fluid",
  "splitMenus": false,
  "fixedHeader": true,
  "fixSiderbar": true,
  colorWeak: false,
  title: '基础管理系统',
  pwa: false,
  logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
  iconfontUrl: '',
};

删除国际化

作为入门学习,而且在实际工作中很少用到国际化,需移除国际化,Ant Design Pro提供了命令可一次性移除所有国际化。

# 运行下面命令移除国际化
$ yarn i18n-remove

【注意】删除后config目录下会生成routes.ts文件,将内容拷贝到routes.js文件中即可。否则项目会报错。

移除顶部帮助文档链接和搜索

src/app.jsx文件中,有个layout导出,顾名思义就是基础布局。
在其配置项中有rightContentRender配置项,用于配置右侧内容,此处就是顶栏右侧内容。 根据组件引用,在src/components/RightContent/index.jsx中找到右侧内容的jsx渲染代码。

return (
    <Space className={className}>
      <HeaderSearch
        className={`${styles.action} ${styles.search}`}
        placeholder="站内搜索"
        defaultValue="umi ui"
        options={[
          {
            label: <a href="https://umijs.org/zh/guide/umi-ui.html">umi ui</a>,
            value: 'umi ui',
          },
          {
            label: <a href="next.ant.design">Ant Design</a>,
            value: 'Ant Design',
          },
          {
            label: <a href="https://protable.ant.design/">Pro Table</a>,
            value: 'Pro Table',
          },
          {
            label: <a href="https://prolayout.ant.design/">Pro Layout</a>,
            value: 'Pro Layout',
          },
        ]} 
        // onSearch={value => {
        //   console.log('input', value);
        // }}
      />
      <span
        className={styles.action}
        onClick={() => {
          window.open('https://pro.ant.design/docs/getting-started');
        }}
      >
        <QuestionCircleOutlined />
      </span>
      <Avatar />
    </Space>
  );

上述代码中的HeaderSearch就是顶栏搜索,QuestionCircleOutlined则是问号图标。 删除相应代码即可

左侧菜单OpenAPI文档和业务组件文档

src/app.jsxlayout导出代码,其中的links配置用于配置侧边菜单的底部链接,删除相应代码即可。

// 相关引用和变量
import { history, Link } from 'umi';
import { BookOutlined, LinkOutlined } from '@ant-design/icons';

const isDev = process.env.NODE_ENV === 'development';

// 布局配置导出
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
  return {
    rightContentRender: () => <RightContent />,
    disableContentMargin: false,
    waterMarkProps: {
      content: initialState?.currentUser?.name,
    },
    footerRender: () => <Footer />,
    onPageChange: () => {
      const { location } = history;
      // 如果没有登录,重定向到 login
      if (!initialState?.currentUser && location.pathname !== loginPath) {
        history.push(loginPath);
      }
    },
    // 此配置用于渲染右侧菜单底部链接
    // links: isDev
    //   ? [
    //       <Link to="/umi/plugin/openapi" target="_blank">
    //         <LinkOutlined />
    //         <span>OpenAPI 文档</span>
    //       </Link>,
    //       <Link to="/~docs">
    //         <BookOutlined />
    //         <span>业务组件文档</span>
    //       </Link>,
    //     ]
    //   : [],
    menuHeaderRender: undefined,
    // 自定义 403 页面
    // unAccessible: <div>unAccessible</div>,
    ...initialState?.settings,
  };
};

底部链接和版权声明

src/app.jsxlayout导出代码,启用的footerRender用于配置系统底部区域。直接删除配置即可。

// 布局配置导出
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
  return {
    rightContentRender: () => <RightContent />,
    disableContentMargin: false,
    waterMarkProps: {
      content: initialState?.currentUser?.name,
    },
    // 此配置用于渲染底部区域
    // footerRender: () => <Footer />,
    onPageChange: () => {
      const { location } = history;
      // 如果没有登录,重定向到 login
      if (!initialState?.currentUser && location.pathname !== loginPath) {
        history.push(loginPath);
      }
    },
    menuHeaderRender: undefined,
    // 自定义 403 页面
    // unAccessible: <div>unAccessible</div>,
    ...initialState?.settings,
  };
};

如果需要底部内容且需要修改成自己的文案,根据Footer组件的引用在src/Footer/index.jsx中找到footer的代码,修改相应属性值即可

export default () => {
  const defaultMessage = '我的系统';
  const currentYear = new Date().getFullYear();
  return (
    <DefaultFooter
      copyright={`${currentYear} ${defaultMessage}`}
      links={[]}
    />
  );
};

【注意】links置空必须传空数组

熟悉UmiJS

Ant Design Pro使用了UmiJS工具搭建的工程,UmiJs是什么? 访问UmiJS官网看到如下标语

插件化的企业级前端应用框架。

怎么又一个框架?和React有什么关系?

在首页的描述中,发现下面这句话

Umi 内置了路由、构建、部署、测试等,仅需一个依赖即可上手开发。并且还提供针对 React 的集成插件集,内涵丰富的功能,可满足日常 80% 的开发需求。

可以简单理解为:对React及其插件进行包装的框架。

UmiJS介绍中有如下描述

为什么不是? create-react-app create-react-app 是基于 webpack 的打包层方案,包含 build、dev、lint 等,他在打包层把体验做到了极致,但是不包含路由,不是框架,也不支持配置。所以,如果大家想基于他修改部分配置,或者希望在打包层之外也做技术收敛时,就会遇到困难。

next.js next.js 是个很好的选择,Umi 很多功能是参考 next.js 做的。要说有哪些地方不如 Umi,我觉得可能是不够贴近业务,不够接地气。比如 antd、dva 的深度整合,比如国际化、权限、数据流、配置式路由、补丁方案、自动化 external 方面等等一线开发者才会遇到的问题。

综上大概可以把它理解成是包含react及其插件、支持脚手架功能及服务端渲染的框架。

Ps. 就是把脚手架功能和服务端渲染的功能封装在一起,同时封装了react的插件集,有种大而全的意思。我个人还是喜欢小而美的东西,这一次我投vue-cli一票。

既然是个框架,那么项目结构应该和原React不一样了,先熟悉一下这个框架,毕竟要基于Ant Design Pro学习React么,Ant Design Pro用它了也没必要非自己搭一套东西。

目录结构

Ant Design Pro就是基于UmiJS搭建的,现有的目录就是UmiJS的目录结构,先熟悉一下目录:

src/.umi 临时文件目录,比如入口文件、路由等,都会被临时生成到这里。不要提交 .umi 目录到 git 仓库,他们会在 umi dev 和 umi build 时被删除并重新生成。这个目录是框架生成的,我们不用管它。

src/app.ts 运行时配置文件,可以在这里扩展运行时的能力,比如修改路由、修改 render 方法等。类似入口文件

src/layouts/index.jsx 约定式路由时的全局布局文件。项目里没有这个目录,不管它。

src/pages目录 所有路由组件存放在这里。 页面组件放置的位置,类似Vue的views目录

目录的作用和其命名基本一致。

配置

UmiJS的配置文件在config/config.js文件中,里面内置了一些配置,可根据需求自行修改。

全部配置参考UmiJS配置,本次不做修改,后续跟进需要在修改。

运行时配置

约定 src/app.jsx 为运行时配置,可以理解为入口文件

modifyClientRenderOpts 修改 clientRender 参数。比如在微前端里动态修改渲染根节点。暂时不考虑微前端,先不管它。

patchRoutes 修改路由。 这个配置暂时可以理解为用于动态添加路由,后续根据需要在试试。

render 覆写 render。比如用于渲染之前做权限校验。这个相当于钩子函数,可以做一些拦截。

onRouteChange 在初始加载和路由切换时做一些事情。比如用于做埋点统计。类似于路由钩子函数,后面应该会用到。

rootContainer 修改交给 react-dom 渲染时的根组件。这个配置估计用不到。

路由

在配置文件中通过 routes 进行配置,格式为路由信息的数组。 配置文件位置config/routes.ts

path 路径,和Vue-router一样的。

component 用于渲染的 React 组件路径。这个和Vue不太一样,估计是UmiJS动态加载的,好处是不用写import了,坏处是IDE路径匹配没用了,万一组件换个位置就gg了。

exact 是否严格匹配,这个Vue没有哈,不过一般也不严格匹配。

routes 配置子路由,Vue-router的是children,我个人更觉得children更加语义化。

redirect 配置路由跳转。重定向,路由都有

wrappers 配置路由的高阶组件封装。 这个高阶组件是React特有的。

title 路由的标题

Ps. 😭 居然没有支持自定义数据的配置,之前Vue页面级组件复用那一套不能玩了么,又得另辟蹊径了。。。

约定式路由

如果没有 routes 配置,Umi 会进入约定式路由模式,然后分析 src/pages 目录拿到路由配置。

动态路由 动态可选路由 嵌套路由 全局 layout 不同的全局 layout 404 路由 权限路由 扩展路由属性

这个挺好,就是得团队成员配合。不配置路由,只修改文件位置就自动生成路由,还是不错的。权限分散到组件里,创意不错。

其他配置

插件 暂时用不到

页面跳转 声明式和命令式,和Vue-router一样。

HTML 模板 类似html入口文件,主要内容就是root根节点和刷新时的DOM动画。

Mock 数据 模拟数据的,拦截返回数据就行么,没什么难点。

环境变量 基于cross-env可以设置不同环境的环境变量

命令行工具 本地开发、打包、校验等等命令

完善项目工程

对UmiJS有了基本的了解之后,大概知道模板每个文件的作用了,下面开始着手整理工程模板。

添加测试、预生产、生产环境变量

Ant Design Pro的环境变量设置和Vue不一样,它是在config目录下通过config.*.ts进行配置的。

.
├── config
│   ├── config.dev.ts             # 开发环境
│   ├── config.test.ts            # 测试环境
│   ├── config.pre.ts             # 预生产环境
│   └── config.prod.ts            # 生产环境

内容如下

import { defineConfig } from 'umi';
export default defineConfig({
  define: {
    BASE_URL: '服务器接口基础路径',
  },
});

调整Pages目录

由于之前Vue的习惯,现在Ant Design Pro的pages目录太乱了,对它的内容进行整理,无用内容删除。

.
├── pages
│   ├── auth             # 账户页面(登陆、注册等)
│   ├── error            # 异常页面(401、404、500等)
│   ├── home             # 首页
│   └── document.ejs     # 模板

修改路由配置

文件调整完了,会造成引用出错,现在调整routes配置

export default [
  { path: '/', component: './home/Home' },
  { path: '/auth/login', name: '登录', layout: false, component: './auth/Login' },
  { component: './error/404' },
]

删除了user的嵌套路由。每个嵌套路由都需要404的路由,因此直接使用一层级路由即可。

结语

通过对ant-design-pro的处理,收获的东西如下:

  1. 系统配置的位置为config/defaultSetting.ts

  2. 项目入口文件为src/app.jsx

  3. src/app.jsx中的layout导出项用于配置系统基础布局。

  4. UmiJs的功能确实很强大,但是有些设计不是很合理(例如.umi目录,html模板位置等)。