baidu / amis

前端低代码框架,通过 JSON 配置就能生成各种页面。
https://baidu.github.io/amis/
Apache License 2.0
17.14k stars 2.48k forks source link

通过json配置页面优势在哪? #2

Closed Leedorado closed 5 years ago

Leedorado commented 5 years ago

首先赞一个👍 我理解好处是修改后台库中的字段就可实时更新页面,避免生产上重复部署; 但采用json来定义页面结果相较于直接写代码工作量感觉并没有减少,而且编辑器各种插件也用不了,所以好奇实际写起来效率如何?

2betop commented 5 years ago

用json其实是一种约束,不直接调用组件,而是通过 json 声明我要什么功能,具体实现不用管!这其实能降低使用者的门槛和成本,不太擅长前端的开发人员也可以用(比如 RD)。这其实就是一种声明式编程的好处。

用户不直接接触组件这一层,而只关心 json 配置的好处是,内部发生技术变更对于用户是无感知的,不会因为升级还要改变写法。

其实在公司内部,还有可视化编辑器,还有平台,在平台上可以直接创建编辑页面。

Leedorado commented 5 years ago

后期会开源可视化编辑器吗?

2betop commented 5 years ago

应该不会,但是可以提供可视化工具(非源码版本)。

Dafrok commented 5 years ago

AMIS 渲染器本质就是把代码中大量重复的 state-to-view mapping 做了一层抽象,并且赋予开发者基于这个规范的抽象的能力。你想用插件也是没有门槛的,AMIS 所有的渲染器都是通过 FormItem 装饰器创建的,你想订制只要给你的组件封装一下即可,你自己订制的渲染器就算是产品经理也可以通过配置 JSON 来生成,说没有减少代码工作量是不可能的。

giscafer commented 5 years ago

有学习参考价值。本人原先业余也搞过类似的工具 ngx-form-builder,用的是ng。一样是通过 jsonschema 来动态创建组件,也是想后期做可视化编辑器,最终也是走回jsonschema——>component的过程。

感谢开源。

realeve commented 5 years ago

@2betop @Leedorado QCon期间很遗憾没听到这次分享,去听头条的消息队列分享去了。

先说结论:

使用JSON配置的方式减少了前端的重复代码开发,新增表单页面可以通过更轻量级的json配置文件来实施,不需要额外重新部署

一、基于MVVM的表单页面的开发流程

假设前端需要写一个页面,提交用户名、邮箱、部门信息至后台,通常我们可能这样来做:

1. 初始化数据

这时你的代码可能长这样子:

<script>
export default {
  data(){
    return{
      email:'',
      username:'',
      department:[]
    }
  },
  methods: {
    async init(){
      let data = await db.fetchDepartment();
      this.department=data;
    }
  },
  mounted() {
    this.init()
  },
}
</script>

或者这样子:

import React,{useState,useEffect} from 'react'
export default function YourComponent(){
  let [state,setState] = useState({
    email:'',
    username:'',
    department:[]
  });
  useEffect(async ()=>{
    let department = await db.fetchDepartment();
    setState({department});
  })

  // ...
}

2. 写好视图

根据上面的数据,结合选用的UI库写好UI层,这时可能需要写好字段的说明如邮箱、姓名、部门,input框还需要placeholder,而邮箱字段可能还需要做数据校验,同时做好数据绑定和事件绑定。

这时一般都会有个【提交】以及【重置】按钮,如果需要数据更新,可能还有个【更新】按钮。

3. 提交数据

通常需要在提交按钮绑定 submit 事件,里面的流程大致是: 数据校验 ——> 拼接参数——> 发送至后台——> 成功/失败后的响应。

说明:在以上的操作中,像selector中部门数据的初始化,UI层中的placeholder,必要的提示信息等都可以做成配置绑定在初始化的state中。

二、基于JSON配置的MVVM渲染

1.抽象数据配置

在写了很多个相似的业务页面以后,我们其实可以将很多工作抽象出来,这就是AMIS所做的工作。 比如一个 文本输入框可能是这样的:

{
            "title": "用户名",
            "type": "input",
            "key": "username", // 这里的key一是用在数组到视图的过程中,虚拟DOM需要传入的key,同时作为数据提交接口的入参字段 

            "rule": {
                "required": true,
                "msg": "请输入有效用户名"
            },
            "placeholder": "请输入用户名",
            "maxLength": 8,
            "toupper": "true"
        }

当发现这样可行以后,逐步添加各种封装组件,根据各个组件的特性设置对应的个性化属性,比如

对下拉框,我们还可以考虑再次封装,加入拼音首字母过滤是否支持复选级联选择等功能。

2.页面初始化配置

通过以上配置能渲染出单个组件后,还需要整体考虑,比如表单的名称、CRUD接口等,这时整个表单的配置可能像下面这样:

{
    "name": "业务表单名称",
    "api": {
        "insert": {
            "url": "81/7e63360284",
            "param": ["rec_time", "uid"],
            "_desc": "insert into tbl_sample_bar(data_type,data_value,data_count ) values (?,?,?)"
        },
        "update": {
            "url": "83/ae9b8e8b0f",
            "param": ["_id"],
            "_desc": "update tbl_sample_bar set data_type = ?,data_value = ?,data_count = ? where id=?"
        },
        "delete": {
            "url": "84/dac2a713d0",
            "param": ["_id"],
            "_desc": "delete from tbl_sample_bar where id=?"
        },
        "query": {
            "url": "82/ef0905c692?param1=2",
            "param": ["data_type", "data_value"],
            "_desc": "SELECT id _id,a.data_type,a.data_value,a.data_count FROM tbl_sample_bar AS a where a.data_type=? and a.data_value=? order by id desc"
        }
    },
    "detail": [
// 页面视图的各个录入组件的配置 
]
}

3.功能逻辑实现

根据JSON中的初始配置,根据我们在传统的MVVM开发流程中调用配置中的CRUD接口做对应的功能实现。

对于需要额外实现的功能,可以根据业务情况不断丰富配置并实现,最终达到只设置json文件便可满足各类表单的业务需求。

4.载入JSON配置

系统URL可能是 http://localhost/form#schema=某业务.json 监听schema的变更,载入对应的 json文件即可。

5.添加至菜单

将URL 【http://localhost/form#schema=某业务.json】 添加至菜单中,这时一个配置式的表单功能页面就完成了


三、为什么使用JSON?

前面的配置信息可以是一个js文件,同时也可以是json,如果是js文件需要考虑eval,或者用全局变量注入,这显示是一种不友好的方式。用json可以以静态资源放在static站,也可以同前台页面一同打包,还可以直接写入数据库,以字符串方式存储,更方便管理。

最后抛砖引玉,本人在前段时间也基于 Antd 做过类似的工作,有了基本功能但没AMIS这么完整,比如没加入表单的横向或纵向排列设置、基于table的crud操作、分步骤的表单填写、弹出dialog创建子表单等:

https://github.com/realeve/sheet_manager/blob/master/src/components/FormCreater/index.tsx

image

image

tomerry commented 5 years ago

好处就是让某些特定领域的业务需求通过拖拽,简单配置,让可视化编程成为可能。json是桥梁

Dafrok commented 5 years ago

简单的说可以把它理解为一种协议啦

w3cmark commented 4 years ago

我们也在做的一个项目:https://vipshop.github.io/ams/

lawbc commented 2 months ago

假如全部用json编写,那么出现一个特殊场景,比如登录的密码需要在发送请求之前前端进行加密,这种如何解决,json又不能写代码,而且还有一个致命的缺点无法注释

realeve commented 1 month ago

@lawbc

假如全部用json编写,那么出现一个特殊场景,比如登录的密码需要在发送请求之前前端进行加密,这种如何解决,json又不能写代码,而且还有一个致命的缺点无法注释

  1. https
  2. 实在需要,对该字段比如 password 增加一个 属性,比如calc, 最后可能是这样的:

// 以下是这个字段的配置 config.json

[
{
 type:'input‘,
key:'password',
title:'密码',
required:true,
calc:'getMD5'
}
]

// fnLib.js ,约定可以使用的函数全部放在这里面

// 假设这是你的getMD5函数
function getMD5(value) {
    // 这里是getMD5函数的实现,以下为伪代码
    console.log('MD5 of ' + value + ' is calculated.');
    // 返回计算结果,这里假设返回一个字符串
    return 'md5-' + value;
}

export default  {
    getMD5: getMD5
};

// 业务解析

import  lib from './fnLib'

// 对字段的处理
const beforeSubmit= (item:{}, yourValueObject:{})=>{
     let key = item.key;
     let val = yourValueObject[key];
     let fnName = item.calc
     if(fnName )
    {
         // 调用函数
        if (typeof lib[fnName] === 'function') {
            let result = lib[fnName ](val);
            return result;
        } else {
            console.error('Function not found');
        }
    }
}