Configurable Platform

185 阅读4分钟
前言

[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配置加少量代码实现区块和模板层面的封装,我们可以按照如下结构,对页面进行分层拆解。