前言
本文主要针对一般项目场景的的开发实战做约束以及具体场景代码写法的描述。
用友云平台战略项目交付团队
目录描述
.
├── LICENSE # 开源协议
├── README.md # 项目脚手架说明
├── package.json # npm packages 依赖包
├── ucf-apps # 【目录名不可修改】微服务应用根目录,用于加载微服务
├── ucf-common # 【目录名不可修改】公共组件、样式、图片、字体等静态资源存放
│ ├── README.md # 描述公共组件等说明
│ └── src
│ ├── components # 公共组件
│ ├── static # 静态资源
│ ├── styles # 公共样式
│ └── utils # 公共方法
├── ucf-publish # 【目录名不可修改】构建出来的静态资源
└── ucf.config.js # ucf 核心配置文件
场景描述
后续内容主要会描述具体场景的代码写法
新建节点(新建模块)
代码结构(强规范)
ucf-cli 1.4.0版本以前
├── app # 节点名称
│ ├── README.md # 描述文件(用于描述节点业务,以及其他记录)
│ └── src
│ ├── components # 业务组件
│ │ └── App # 这里是示例,组件命名需按照具体业务来定
│ │ ├── index.js # 一级目录或默认导出组件文件命名为index.js
│ │ └── index.less #
│ ├── routes # 路由
│ │ └── index.js #
│ ├── app.js # 入口文件
│ ├── container.js # 容器
│ ├── index.html #
│ ├── model.js # 数据模型,数据业务层
│ └── service.js # 接口业务
ucf-cli 1.4.0版本及以后
├── app # 节点名称
│ ├── README.md # 描述文件(用于描述节点业务,以及其他记录)
│ └── src
│ ├── components # 业务组件
│ │ └── App # 这里是示例,组件命名需按照具体业务来定
│ │ ├── index.js # 一级目录或默认导出组件文件命名为index.js
│ │ └── index.less #
│ ├── routes # 路由
│ │ └── index.js #
│ ├── app.js # 入口文件
│ ├── index.html #
│ ├── model.js # 数据模型,数据业务层
│ └── service.js # 接口业务
代码描述
- 新建组件
```less // App/index.less 文件 //注入全局变量,该文件主要是定义了一些默认颜色的变量 @import ‘~styles/variables.less’; / 由于类似业务较多,防止被覆盖,我们通过上下文控制样式的作用域。class 名的命名规则统一采用 iuap-- 规范来命名,比如当前节点为 iuap-test 工程下的 App 模块,则命名为 iuap-test-app。 / / 通过上下文控制后,内部在命名为各自的组件即可,如app模块下的 App 组件 /// App/index.js 文件
// js描述
import React, { Component } from 'react';
import './index.less';
//组件名称需遵守大驼峰命名法,同时需根据业务需能简单描述业务场景
class App extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
/**
* 注意 const 和 let 的使用,根据具体代码逻辑修饰符。禁止
* 全篇一个修饰符,const 一般用于描述名义上的常量,做说明性
* 描述,
*/
//方法体内默认缓存 this 对象,并命名为常量的 _this;
const _this = this;
return (
<div className='app'>
</div>
)
}
}
export default App;
.[工程名]-[节点名]{
.[组件名]{
}
}
```less
@import '~styles/variables.less';
//当存定义一个例如 OrderList 组件时,样式写法如下。
.iuap-test{
.order-list{
}
}
ucf-cli 1.4.0版本以前
// ucf-cli 1.4.0版本以前
import React from "react";
import {Route} from "mirrorx";
import {ConnectedOrg} from "../container";
export default () => (
// 定义好样式作用域后通过在总路由中增加样式名的方式做全局控制
<div className="route-content iuap-test">
<Route exact path='/' component={ConnectedOrg}/>
</div>
)
ucf-cli 1.4.0版本及以后
// ucf-cli 1.4.0版本以前
import React from "react";
import mirror, { Route,connect } from 'mirrorx';
import App from '../components/App/index';
import model from './model'
mirror.model(model);
const ConnectedOrg = connect(state => state.home,null)(App);
export default () => (
// 定义好样式作用域后通过在总路由中增加样式名的方式做全局控制
<div className="route-content iuap-test">
<Route exact path='/' component={ConnectedOrg}/>
</div>
)
注意:上述过程描述常规业务场景,复杂业务场景可依照具体场景做适当调整。
路由写法
/**
* 前端路由说明:
* 1、基于浏览器 History 的前端 Hash 路由
* 2、按业务模块和具体页面功能划分了一级路由和二级路由
*/
import React from "react";
import { Route } from "mirrorx";
import { ConnectedApp } from "../container";
export default (props) => {
return <div className="route-content">
<Route exact path={`${props.match.url}`} component={ConnectedApp}/>
<Route exact path={`${props.match.url}app`} component={ConnectedApp}/>
</div>
}
注意:${props.match.url}app 在模板之后没有斜线
service.js 写法
在编写service
时需先明确在ucf.config.js
中注入了对应后台的项目名的全局变量,以及设置了相关代理。// service.js
import request from "utils/request";
//注意接口名的定义规范
const URL = {
//严禁使用这种写法
"GET": `http://10.5.6.55/iuap/server`,
//尽量避免这种写法
"SAVE": `iuap/server`,
//规范写法
"SAVE_ONE": `${GLOBAL_HTTP_CTX}/server`
}
/**
* 获取列表
* @param {*} params
*/
export const getItemList = (param) => {
return request(URL.SAVE_ONE, {
method: "post",
data : param,
});
}
// ucf.config.js
require('@babel/polyfill');
module.exports = (env, argv) => {
return {
...
// 代理的配置
proxy: [
{
"enable": true,
"headers": {
"Referer": "http://127.0.0.1:8180"
},
"router": ["/split"],
"url": "http://127.0.0.1:8180"
}
],
// 全局环境变量
global_env: {
GROBAL_HTTP_CTX: JSON.stringify("/iuap"),
}
...
}
}
公共方法和公共组件
我们的公共组件和方法在
ucf-common
中,通用组件的开发请参考项目最佳实践-构建前端工程之第三章.
├── ucf-common # 【目录名不可修改】公共组件、样式、图片、字体等静态资源存放
│ ├── README.md # 描述公共组件等说明
│ └── src
│ ├── components # 公共组件
│ │ ├── Alert # 简单 alert 组件封装,可用于删除等提示性交互操作
│ │ ├── AsyncComponent.jsx # 可异步加载的组件
│ │ ├── AsyncLoad.js # 可异步加载的组件
│ │ ├── Button # 带图标按钮的简单封装
│ │ ├── ButtonRoleGroup # 按钮权限相关组件
│ │ ├── DelModal # 用于删除提示固定场景使用的组件
│ │ ├── FormControlPhone #
│ │ ├── FormError # Form 经典场景的校验错误提示
│ │ ├── Grid # 通用 Grid 组件封装
│ │ ├── Header #
│ │ ├── NoData #
│ │ ├── PaginationTable #
│ │ ├── Pop #
│ │ ├── RefControl #
│ │ ├── RefOption #
│ │ ├── RefViews #
│ │ ├── RowField #
│ │ ├── SearchCascader #
│ │ ├── SearchPanel #
│ │ ├── SelectComp #
│ │ ├── SelectMonth #
│ │ └── SelectViews #
│ ├── static # 静态资源
│ ├── styles # 公共样式,复写的 tinper-bee 中组件的样式
│ │ ├── button.less #
│ │ ├── grid.less #
│ │ ├── styles.less # 通用样式
│ │ └── variables.less # 全局样式变量
│ └── utils # 公共方法