前言
[bradfrost.com/blog/post/a…](Atomic Design)是前端开发圈中众所周知的设计理论,尤其是在中台类型的UI开发中。基于vue.js的element-ui、iview-ui和基于react.js的Ant Design都是该设计理论的最佳实践。 但是这些项目,更多的是关注于组件,在我看来,就是原子这个层面。那么对于区块或者模板呢? 我们能不能将中台开发中的典型场景进行抽离和封装,来实现模板、区块层面的复用呢? 针对这个问题,我们整合出一套基于JSON配置和vue-cli插件机制的模板复用方案。
对于模块、区块、模板等部分,社区也有很多尝试,如阿里的ICE,通过区块市场、模板市场来实现区块和模板的共享
一、背景
在做管理后台的前端开发时,我发现以下问题:
(1)、重复开发太多 增删改查、权限管理、数据报表、信息监控、信息审核这些场景作为中台开发的常见需求,在无数个平台中被一遍又一遍的实现
(2)、代码维护问题VS项目复杂度的上升和人员流动性:
即使我们尝试用标准的文档来管理API,对代码进行组件化,模块化分层处理,但仍避免不了中台开发后期,庞大而冗长的表单代码,各种模块中掺杂的特殊处理带来的项目理解和代码维护问题;
二、前端UI拆解
页面<-模板<-区块<-模块<-组件
典型的前端产品,都可以拆解为如下形式:Layout 和 Page

按照bradfrost.com/blog/post/a…,对一个典型的增删改查页面进行拆解,可以得到下图:

通过UI拆解,我们发现:对于一个增删改查页面,不论是区块,还是模板,其相同的部分是具有固定的页面结构、交互形式,而变化的部分,通常都是数据和具体的表单控件形式;

如果我们可以将固定的部分通过编码来实现形成模板,并把变化的部分抽离出来,通过JSON配置来声明。
这样就可以一定程度的减少重复工作及代码维护性问题,因为:
(1)、一个项目,甚至多个项目中,只要是功能相似,结构相同的页面,都可以复用一套模板代码,或者基于一套模板代码来扩展,可以提高代码复用率,进而提高开发效率;
(2)、模板代码量不涉及变化的部分,诸如表单控件、表格数据等都被抽离出来通过JSON表单,后续发生变更,仅需更新相关配置即可;
那么模板要如何封装,才能保持其灵活性和可扩展性?JSON配置如何覆盖那么多的可变化性呢?
三、JSON可配置
CP通过实现基于JSON配置的基础工具来完成组件、模块、区块、模板的JSON可配置。 如下展示了通过表单工具,来实现输入框、登录表单、增删改查页面,从而使JSON配置的能力可以覆盖到UI分层的各个部分。
1、通过JSON配置一个Input组件

<script>
export default {
data() {
return {
field: {"type":"Input","model":"name"},
model: {"name":"json"}
};
}
methods: {
handleFieldChange(model, value) {
console.log(model, value);
}
}
};
<script>
<template>
<Form :model="model">
<FieldGenerator
:field="field"
/>
</Form>
</template>
2、通过JSON配置一个登录表单

<script>
const fields = [
{
"type": "Input",
"model": "username",
"placehold": "Username",
"prefix": "ios-person-outline",
"width": 120,
"rules": [
{
"required": true,
"message": "Please fill in the user name",
"trigger": "blur"
}
]
},
{
"type": "Input",
"subtype": "password",
"model": "password",
"placehold": "Password",
"prefix": "ios-lock-outline",
"width": 120,
"rules": [
{
"required": true,
"message": "Please fill in the password.",
"trigger": "blur"
},
{
"type": "string",
"min": 6,
"message": "The password length cannot be less than 6 bits",
"trigger": "blur"
}
]
},
{
"type": "Submit",
"subtype": "primary",
"text": "登录",
"width": 80
}
];
const model = {
"username": "",
"password": ""
};
const options = {
"inline": true
};
export default {
data() {
return {
fields,
model,
options
};
},
methods: {
handleSubmit(formName) {
console.log(this.$refs[formName].model);
}
}
};
<script>
<template>
<FormGenerator
:fields="fields"
:options="options"
:model="model"
@on-submit="handleSubmit('form')"
/>
</template>
3、通过JSON配置一个增删改查功能页

具体实现的代码可以查看:json-drived-configurable-platform.github.io/cp/#/concep…
四、CP分层设计
当我们可以通过JSON配置加少量代码实现区块和模板层面的封装,我们可以按照如下结构,对页面进行分层拆解。
