在我们学习 Ant Design Pro V5 的时候,我们要简单了解下他是如何调用组件,页面执行顺序等,也是学习这个框架中不可缺少的一环

目录结构

关于目录结构这块,增加公共页面类,存放公共页面类,便于开发~

  1. ├── config # umi 配置,包含路由,构建等配置
  2. ├── mock # 本地模拟数据
  3. ├── public
  4. └── favicon.png # Favicon
  5. ├── src
  6. ├── assets # 本地静态资源
  7. ├── commonPages # 公共页面
  8. ├── components # 业务通用组件
  9. ├── e2e # 集成测试用例
  10. ├── layouts # 通用布局
  11. ├── models # 全局 dva model
  12. ├── pages # 业务页面入口和常用模板
  13. ├── services # 后台接口服务
  14. ├── utils # 工具库
  15. ├── locales # 国际化资源
  16. ├── global.less # 全局样式
  17. └── global.ts # 全局 JS
  18. ├── tests # 测试工具
  19. ├── README.md
  20. └── package.json

页面代码结构推荐

这里建议将接口单独分离出来~

  1. src
  2. ├── components
  3. └── pages
  4. ├── Welcome // 路由组件下不应该再包含其他路由组件,基于这个约定就能清楚的区分路由组件和非路由组件了
  5. | ├── components // 对于复杂的页面可以再自己做更深层次的组织,但建议不要超过三层
  6. | ├── index.tsx // 页面组件的代码
  7. | └── index.less // 页面样式
  8. | └── interface.d.ts // 页面复杂,单独把ts拿出来
  9. | └── services.ts // 接口
  10. | └── mock.ts // 模拟数据,大部分不需要

页面执行顺序

1.首先执行

我们先看看 /scr/app.tsx 这段代码
image.png
image.png
首先页面打开(无论哪个页面都会执行),会执行 app.tsx 里的 getInitialState ,然后走向queryCurrentUser 这个函数,在这个函数上他会判断 access 是否存在,如果不存在则会报错,发送状态码为401, 然后就会走向登录页面,反之则会停留在当前页面

2.抵达登录页面

image.png
到达登录页面后。输入账号密码时走向 fetchUserInfo 这个方法,这个方法主要的作用是存储了一开始登录接口所需的函数
注意,这里进去的页面不会执行 getInitialState 这个函数,所以再次要执行获取用户信息的方法

3.页面切换

我们做的页面会放在浏览器上,我们需要登录信息才能够打开,但由于许多外部原因会导致存储的信息发生变化,如清储缓存,时间过长导致登录信息失效等,那么在 V5 中如何判断的呢?

会将登录信息放在 initialState 中,我们需要在 app,tsx 中的 onPageChange 这个方法里

image.png

这个方法是通过页面转换而触发的,在这里也会判断用户信息是否存在,如果不存在,则会重新跳转登录界面

UI设置

1、@ 做了什么

我们随意的可以看见类似这样的引入

  1. import Footer from '@/components/Footer';

那么 @是干嘛的呢?
其实在项目中引入分为绝对路径和相对路径,我们通常将组件放置在 component 模块下,配置放置在 utils模块下,那么 @ 实际上就是 相当于绝对路径 也就是 /src 的作用,他就是别名

帮助我更快速的引入,详细的可参考 webpack别名设置

2、简单的数据流

中后台场景下,绝大多数页面的数据流转都是在当前页完成,在页面挂载的时候请求后端接口获取并消费,这种场景下并不需要复杂的数据流方案。但是也存在需要全局共享的数据,如用户的角色权限信息或者其他一些页面间共享的数据。那么怎么才能缓存并支持在多个页面直接去共享这部分数据呢。简而言之,就是状态管理

状态管理相信大家首先想到的 redux ,其次是 mobx,那么在Ant Design Pro 中用了什么来更好的管理状态呢?

在 V4 的版本中主推的 dva 数据流,这里就不详细介绍了

那么在 V5 中呢?毫无疑问,官方设置的更加简便,相对于 redux、mobx、dva那简直简单的太多了,相对于是傻瓜式操作~

  1. import { useModel } from 'umi';
  2. const { initialState, setInitialState } = useModel('@@initialState');

只需要 引入 useModel 就可以进行使用了

initialState: 数据
setInitialState: 设置数据

优化配置

我们不难发现 initialState 是整个项目的灵魂,他是初始化的数据,为了简便,我们把他提取出来,从而更改全局的配置

位置: /src/utils/initData

之后所有的操作都可以放到这个文件去做初始化数据,他返回的对象就是 useModel('@@initialState') 里的值

  1. /**
  2. * @module 初始化方法
  3. */
  4. const initData = async () => {
  5. const currentUser = await queryCurrentUser()
  6. // 动态路由:menuData接收的为路由的函数,为false时,不启动动态路由
  7. // const menuData: MenuDataItem[] = await getMenuData()
  8. return {
  9. currentUser: currentUser,
  10. content: content,
  11. // menuData: formatter(menuData), // 示例,动态路由
  12. menuData: false,
  13. domesy:{
  14. layoutSy,
  15. pageLayoutSy,
  16. tableSy,
  17. fromSy,
  18. maskSy,
  19. CardSy,
  20. storageSy,
  21. OssUpLoadSy,
  22. }
  23. }
  24. }

另外我在原有的基础上设置了一些简便的方法,后续会讲到~