Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

order0
title开始使用
type入门

架构介绍

写在前面

此架构提供了以下的典型模板,并据此构建了一套基于 React 的中后台管理控制台的脚手架,可以快速搭建企业级中后台产品。

- Dashboard
- 分析页
- 监控页
- 工作台
- 表单页
- 基础表单页
- 分步表单页
- 高级表单页
- 列表页
- 查询表格
- 标准列表
- 卡片列表
- 搜索列表(项目/应用/文章)
- 详情页
- 基础详情页
- 高级详情页
- 结果
- 成功页
- 失败页
- 异常
- 403 无权限
- 404 找不到
- 500 服务器出错
- 帐户
- 登录
- 注册
- 注册成功

谁在使用

目前蚂蚁金服和阿里巴巴内部多个项目使用了这个架构, 以下是使用React技术�开发的网站 .

微软VS文档介绍

微软outlook邮箱

Pluralsight培训

知乎

前序准备

本地环境需要安装 nodegit。我们的技术栈基于 ES2015+React、 和 antd:前端UI库

安装

直接 clone git 仓库

$ git clone --depth=1 https://github.com/restry/antpro.git my-project
$ cd my-project

目录结构

完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

├── mock # 本地模拟数据
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── common # 应用公用配置,如导航信息
│ ├── components # 业务通用组件
│ ├── layouts # 通用布局
│ ├── models # 数据模型 model
│ ├── routes # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── g2.js # 可视化图形配置
│ ├── theme.js # 主题配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 应用入口
│ ├── index.less # 全局样式
│ └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

$ npm install

如果网络状况不佳,可以使用 cnpm 进行加速。

$ npm start

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

接下来就可以修改代码进行业务开发了,内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、全局路由等等各种实用的功能辅助开发。

官方在线预览


添加页面

因为是SPA单页应用程序, 在添加页面之前需要先明白什么是路由, 它是组织起一个应用的关键骨架,脚手架提供了一些基本的工具及模板,帮助更方便的搭建。

前序知识

通常根据不同的业务需求, 路由可以分为以下两种:

  • 可以利用现有布局及导航展示规则,只是新增页面

    这种情况下,只需要对导航数据进行增删,就能完成路由和导航的配置。

  • 新增页面有不同的布局

    修改数据的同时,还需要你新建布局文件,还可能需要自己生成相应的导航,或对现有规则进行调整。

大部分情况下,我们不会有新的布局. 下面简单介绍两种情况下如何添加路由。

添加页面/路由

添加页面

这里的『页面』指配置了路由,能够通过链接直接访问的区域,只需要在脚手架的基础上进行简单的配置。


一、新增 js、less 文件

src/routes 下新建页面的 js 及 less 文件,如果相关页面有多个,可以新建一个文件夹来放置相关文件。 less也不是必需. 如果页面有单独的样式需求, 就可以添加进去. 否则使用全局样式即可

新增页面


样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件

@import"~antd/lib/style/themes/default.less";

这样可以很方便地获取 antd 样式变量并在文件里使用,有利于保持页面的一致性,也方便实现定制主题。

三、新增 model

布局及路由都配置好之后,回到之前新建的 NewPage.js,可以开始写业务代码了!如果需要用到数据交互, 比如与后台交互数据,考虑到开发规范与流程化, 我们使用了DVA来进行状态管理. DVA是基于Redux与Redux-Saga封装的一个组件. 简单易用. 然后在 src/models 中建立相应的 model,具体可以参考脚手架内置页面的写法。

添加路由

脚手架默认提供了两种布局模板:基础布局 - BasicLayout 以及 账户相关布局 - UserLayout

基础布局

账户相关布局

如果页面可以利用这两种布局,那么只需要在导航数据中增加一条即可。打开文件 src/common/nav.js,添加页面信息:

{name: '新页面',// 页面名称,会展示在菜单栏中path: 'new',// 匹配的路由icon: 'file',// 页面图标,会展示在菜单栏中component: dynamicWrapper(app,['NewPageModel'],()=>import('/routes/NewPage')),// 动态引入NewPage页面和所需的Models}

加好后,会默认生成相关的路由及导航。访问 http://localhost:8000/#/new 就可以看到新增的页面了。

新增页面

到这一步,路由和页面就建好了。

带参数的路由配置

src/common/nav.js 中这样配置即可:

{name: '详情页',path: 'profile',icon: 'profile',children: [{name: '基础详情页',path: 'basic',component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/BasicProfile')),},{name: '高级详情页',path: 'advanced',children: [{name: '高级详情页',path: ':id',// id 为参数名component: dynamicWrapper(app,['profile'],()=>import('../routes/Profile/AdvancedProfile')),}]}],}

添加组件

对于一些可能被多处引用的功能模块,建议提炼成业务组件统一管理。这些组件一般有以下特征:

  • 只负责一块相对独立,稳定的功能;
  • 没有单独的路由配置;
  • 可能是纯静态的,也可能包含自己的 state,但不涉及数据流,仅受父组件(通常是一个页面)传递的参数控制。

下面以一个简单的静态组件为例进行介绍。假设你的应用中经常需要展现图片,这些图片宽度固定,有一个灰色的背景和一定的内边距,有文字介绍,就像下图这样:

你可以用一个组件来实现这一功能,它有默认的样式,同时可以接收父组件传递的参数进行展示。

新建文件

src/components 下新建一个以组件名命名的文件夹,注意首字母大写,命名尽量体现组件的功能,这里就叫 ImageWrapper。在此文件夹下新增 js 文件及样式文件(如果需要),命名为 index.jsindex.less

在使用组件时,默认会在 index.js 中寻找 export 的对象,如果你的组件比较复杂,可以分为多个文件,最后在 index.js 中统一 export,就像这样:

// MainComponent.jsexportdefault({ ... })=>(...);// SubComponent1.jsexportdefault({ ... })=>(...);// SubComponent2.jsexportdefault({ ... })=>(...);// index.jsimportMainComponentfrom'./MainComponent';importSubComponent1from'./SubComponent1';importSubComponent2from'./SubComponent2';MainComponent.SubComponent1=SubComponent1;MainComponent.SubComponent2=SubComponent2;exportdefaultMainComponent;

你的代码大概是这个样子:

// index.jsimportReactfrom'react';importstylesfrom'./index.less';// 按照 CSS Modules 的方式引入样式文件。exportdefault({ src, desc, style })=>(<divstyle={style}className={styles.imageWrapper}><imgclassName={styles.img}src={src}alt={desc}/>{desc&&<divclassName={styles.desc}>{desc}</div>}</div>);
// index.less
.imageWrapper {
padding:020px8px;
background:#f2f4f5;
width:400px;
margin:0 auto;
text-align: center;
}
.img {
vertical-align: middle;
max-width:calc(100%-32px);
margin:2.4em1em;
box-shadow:08px20pxrgba(143,168,191,0.35);
}

到这儿组件就建好了。

使用

在要使用这个组件的地方,按照组件定义的 API 传入参数,直接使用就好,不过别忘了先引入:

importReactfrom'react';importImageWrapperfrom'../../components/ImageWrapper';// 注意保证引用路径的正确exportdefault()=>(<ImageWrappersrc="https://os.alipayobjects.com/rmsportal/mgesTPFxodmIwpi.png"desc="示意图"/>;)

和服务器端交互

前后端分离开发,提供本地模拟数据给前端代码调用的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作。下面将简单介绍和服务端交互的基本写法。

前端请求流程

一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect; // 类似vuex或者redux的dispatch
  3. 使用封装的 request.js 发送请求;
  4. 获取服务端返回;
  5. 然后调用 reducer 改变 state;
  6. 更新 model。

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Effect 处理异步请求

在处理复杂的异步请求的时候,很容易让逻辑混乱,陷入嵌套陷阱,所以底层基础框架使用 effect 的方式来管理同步化异步请求:

effects: {*fetch({ payload },{ call, put }){yieldput({type: 'changeLoading',payload: true,});// 异步请求 1constresponse=yieldcall(queryFakeList,payload);yieldput({type: 'save',payload: response,});// 异步请求 2constresponse2=yieldcall(queryFakeList2,payload);yieldput({type: 'save2',payload: response2,});yieldput({type: 'changeLoading',payload: false,});},},

通过 前面加星号 generatoryield 使得异步调用的逻辑处理跟同步一样


API 文档自动生成

在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难点给阻塞住,从而保证项目进度。

在此架构中已经有了一套比较完善的 mock 功能,而 roadhog-api-doc 工具,则能够从项目的 mock 数据中读取接口信息生成对应的文档,这样就能够更加清晰明了的展现项目的接口情况。

如何使用

$ npm install roadhog-api-doc -g

本地服务

进入到项目根目录,运行:

$ roadhog-api-doc start [port]

书写文档

通常来讲,你无需额外加入任何依赖就可以生成文档,但是如果你需要对接口做出说明,需要按照以下格式对 roadhog mock 文件进行修改:

$ npm install roadhog-api-doc --save-dev // 将 roadhog-api-doc 作为本地工具依赖安装
import{format}from'roadhog-api-doc';constproxy={'GET /api/currentUser': {$desc: "获取当前用户接口",$params: {pageSize: {desc: '分页',exp: 2,},},$body: {name: 'momo.zxy',avatar: imgMap.user,userid: '00000001',notifyCount: 12,},},};exportdefaultformat(proxy);

其中:

  • $desc: 接口说明
  • $params: 接口参数说明,对象描述各个参数的意义
  • $body: 数据返回结果,通常就是 mock 的数据

本地测试 mock 数据和真实端口

当启动本地的 API Docs 站点以后,可以点击 send 按钮发送 POST 或者 GET 请求,并且返回值会在弹出框中显示:

其中需要注意的是,如果启动 API Docs 站点时,没有加端口号,那么这里的返回数据是静态数据,如果加了端口号并且本地也同时跑起了项目,那么就会直接返回实际数据。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages