简单记录一下百度 lowcode 框架 amis 的封装历程。
什么是 lowcode
前端真的太卷了,总是会出现一些莫名其妙的新概念、新名词。
但仔细看往往会发现,其实不是什么新技术,而是旧的思想焕发新生。
lowcode 指的是低代码开发,是通过配置或者图形化,来生成程序。
在上家公司做的拖拽生成页面的项目,也算是 lowcode 了。
对于前端来说,很主要的一个应用就是通过配置生成界面。
为什么要用 lowcode 开发前端
admin 团队,主要维护内部系统。
内部系统的需求,往往都是增删改查数据。
例如一个库存系统,主要页面就是 => 列表页,查询记录,详情页,增加一个条目,编辑一个条目,删除一个条目。
此模式的的页面,占总页面的比例很大。
并且因为功能相似,代码较为重复,会耗费很多无意义的开发时间。
这种页面的常见模式一般是:
1 | 列表页:表单+按钮+表格 |
把这种模式的页面抽象起来,变成用配置描述的形式,如:
1 | { |
通过配置的形式,快速生成 vue 组件,最后生成页面,可以减少开发时间。
后期文档完善后,甚至可以让产品同学直接参与配置页面。
当功能成熟以后,也可以作为一种新的约束、规范,避免设计出奇奇怪怪的交互。
但这也不是没有缺点。
所有的工具,能力都是有边界的,lowcode 没有办法顾及所有形式的页面。
复杂的的场景还是需要单独开发的。
选型
lowcode 其实已经有一些成熟的框架了,例如百度的 amis, 例如 umijs/sula。
鉴于 amis 的 star 数量远远超过其他,社区也比较完善:
- 由百度团队维护
- 大量内置组件(100+)(内容丰富)
- 支持自定义组件来拓展 (拓展能力强)
- 经历了长时间的实战考验 (bug 少,使用人数多)
所以选择了 amis。
目前团队使用的技术栈是 vue, 但 amis 是基于 react 开发的,这就需要经过一层转换了。
利用高阶组件的原理,可以将 amis 封装转换成 vue 可用的组件。
实现目标
最终需要实现的效果是:暴露一个函数,入参为 json 配置,输出一个 vue 组件。
1 | renderer(json, options) { |
思路如下图
- amisRender() 会生成一个 React 组件
- 我们在 React 组件上层包裹一层 Wrapper 组件(Vue)
- 最后实现一个 renderer() 方法,再对第 2 步的 Vue 组件做一层包装,返回新的 Vue 组件

第一步:实现 Wrapper 组件(Vue)
- html 模板。我们定义一个 Vue 组件的模板,包含一个元素,元素节点引用名称为 ’amis‘。
1 | <template> |
- 引入 amis 相关文件以及 React
1 | <script> |
- 组件接受一个 json 串,因此定义一个 prop,名为 schema
1 | export default { |
- 在组件 mounted 后,我们开始使用 react 挂载 amis。
1 | export default { |
- mountReactComponent 方法具体写法
1 | export default { |
- 完整代码
1 | <template> |
以上是 Vue 组件的包装,但只是简化的代码,实际情况并没有那么简单。
我们还需要加入:
- 权限拦截
- 多语言
- 弹窗,confirm 等组件
- 实现 fetcher 中的请求方法自定义
- …
这些部分涉及业务逻辑,在这里我就不写了。
第二步:实现 renderer 函数。
Vue 组件实现完成后,接下来实现 renderer 包裹层。
这里使用了 vue-compose 这个库,这个库可以实现类似 vue.extend 的功能
vue-compose 提供的 compose 方法,接受一个 vue 组件或者类 vue 对象,生成一个新的 vue 组件。
1 | import { compose, withProps } from 'vue-compose' |
使用
经过上面的两步封装,已经可以正常使用了。
先按照 amis 的规范,写一份 json 配置文件。
这里用 JSON.stringify 序列化了,是为了防止出现 json 格式错误:
其中:
- title 是页面标题
- body 是页面内容,类型是 form 表单
- initApi 是用来初始化表单的 api
- controls 是表单项,可以使 input, select, 或者纯文案
- table 作为表单项的一部分
- action 是表单的操作按钮,按钮有一系列行为,例如页面跳转,或者请求接口
1 | // my-schema.js |
接下来,找到项目的 router 路由,引入 json 和 renderer 函数
使用 renderer(json) 生成 vue 组件,并作为 router 的 component 传入。
1 | // 引入函数 |
使用 lowcode 的缺点在于配置项异常繁杂,需要一定的时间成本来学习配置项。
所以在初期,需要投入的开发时间甚至多于直接写代码的时间。
但从长久来看,只要配置稳定,上手之后仍然是可以节省很多时间的。