目录
1. 珊瑚海介绍
CoralSea官网: http://doc.58corp.com/CoralSea
珊瑚海是安居客发起,58无线团队参与共建的一站式动态布局框架,支持 Android、iOS、小程序、H5. 包含引擎框架、DSL 管理后台、可拖拽低代码前端、JS 开发框架等全套基础能力。适用于 UI 交互、动画复杂性较低、布局动态要求高的页面。
一站式工具链:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_gradle_WebHome_coralsea_design_effect.jpg)
- 轻量级,快速接入
接入改造成本低,仅需少量的代码进行接入,包大小只增加 100k
- 跨平台
底层使用 Yoga,支持 Android、iOS、小程序、H5,高度的 UI 一致性
- 性能优
高性能,Yoga 底层 C++ 实现,可用于首页、混合页面,列表滑动丢帧率低
- 替换客户端列表、卡片开发模式
新的列表、卡片样式,可以内置在 App 中,提前编译成原生代码(低代码+跨端+性能),无 DSL 加载解析过程,扁平化性能更优
- 丰富的基础组件、事件,支持自定义
基础组件、事件丰富,支持注册自定义组件、事件
- 支持卡片级别的动态化,高可复用性
支持基于卡片级别的动态化,DSL 文件更小。高复用性,一套卡片可用于不同页面。DSL 前端提供卡片仓库,开发、上线更快捷
- 支持页面的动态化
少量代码即可让整页面作为布局动态化载体
- DSL 管理后台一站式上线发布
提供 DSL、模版创建、修改、发布的一站式服务
- 低代码前端支持拖拽、sketch 导入
低代码前端操作便捷,适用于各种角色
- 低代码前端支持 RN、Flutter 对接
打造大前端 DSL 生态
1.1 58同城预接入效果
DSL 管理后台 + 低代码前端:
App:
描边卡片为珊瑚海卡片:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_gradle_WebHome_58App_effect.jpeg)
1.2 安居客落地业务
珊瑚海房价卡片页面:
- 一套DSL跨Android/iOS,跨58App/安居客,开发成本节省 50%
- 体验与原生一致,具备 RN 的热更新能力,性能优于 RN 30%
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_anjuke_cr1.jpg)
房产909项目经纪人门店单页
- 使用珊瑚海 + BFF,9月上线以来热修复问题1次,覆盖率 100%
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_anjuke_cr2.jpg)
整改需求- 删除当前APP的服务痕迹
- 跨 Android & iOS,表单展示类页面,0.5人/日快速开发完成
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_anjuke_cr3.jpg)
1.3 后期落地计划
# | 业务 | 解决的痛点 |
---|---|---|
1 | 58同城厂商包 | 1. 快速响应厂商问题 2. 优化包大小 |
2 | 58同城、58本地版市场包 | 1. 瀑布流卡片动态化,为多元化场景赋能 2. 高效率编译期 DSL,提供一种全新的 UI 开发模式 |
2. 与其他框架的对比
2.1 布局动态化你要理解的一些概念
目前市面上的跨端框架层出不穷,RN、Hybrid、Flutter、小程序,除了需要具备跨端的能力,在动态性、多端一致性、性能、包大小等方面要求也越来越高。每种框架都有自己独特的优势和不足,不同公司、不同业务、不同时期在这些框架的选择上都存在不同。
在评价跨端框架上,我们一般会从几个方面来看:
- 研发效率
- 动态化
- 多端一致性
- 性能体验
- 生态
那么为什么会衍生出布局动态化这种框架呢?以 58同城 APP 为例,产品需要快速验证 UI 效果,运营需要经常上线各种活动。
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_wafers图片_WebHome_mocha_home_ab_test.jpg)
主流的跨端框架大多过重,无论是 H5 还是 RN、Flutter 类的方案,它们动态化能力的关键在于随时可发布代码,是面向开发的动态化方案,发布代码意味着开发、测试、灰度等一系列流程都要完整跑通,显然难以满足产品和运营的诉求。
同时在现有工程中使用,对于包大小、接入成本、性能等有着严格地限制,RN 当前的版本依托于 Bridge,无法用于首页 (最新版使用 JSI、Hermes,但内存占用是问题),Flutter 与混合工程对接、动态化、包大小、运行内存一直被诟病,H5 性能更差,冗长的栅格化绘制流程慢的让人抓狂。
当然每种框架都有特定适用的场景,一般大型 APP 都是多套框架并存。
当然中间我们也做过一些尝试,比如基于 Android App Bundle + Qigsaw 的任意门、Mocha,实现了基于版本级别的线上 AB 测能力:
业务线接入情况:无线、招聘、部落、二手车
使用情况:任意门进行 bug 修复 3次,AB 测 6次
动态包覆盖速度:动态包安装量 7天 能覆盖活跃用户的 90% 以上
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_renym.jpg)
任意门、Mocha 性能与原生无异,具备彻底地动态化能力 (dex、so、资源),但其存在一些限制,特别是在纯布局动态化场景下:
- 只支持 Android
- 基于版本级别,PM 如果想跨版本连续验证效果,则需要打包、上线多次
2.2 布局动态化框架需要具备哪些能力?
-
DSL 布局描述文件: 一般为 json(简单易用)、xml(直观)、ProtoBuf(性能、大小) 格式。无论是 H5 还是 RN,动态化都需要有描述页面结构的语言。H5 和 RN 为了追求开发模式的完备,各自定义了一套通用编程语言 (GPL),比如 RN 的 JSX.
-
可视化编辑前端/工具: 用于编辑产出 DSL
-
管理后台: 用于产品管理、DSL 管理,可快速编辑、发布上线
-
端侧引擎: 基础的组件、事件,下载、解析、运行 DSL
-
可扩展能力: 组件、事件等业务可定制扩展
2.3 布局动态化框架间的对比
Tangram、VirtualView
Tangram、VirtualView 是业内比较知名的布局动态化框架,同时其具备其他框架没有的组件动态更新能力,所以这边和它对比一下。
优点:
- 跨端支持:支持
- 性能: 性能优,底层 C 实现,同时具备扁平化能力
- 组件与动态能力:内置布局、组件丰富,开放的 API,同时 VirtualView 具备动态更新组件的能力
缺点:
- 更新维护:最新更新在 2020/12
- DSL 前端、管理后台未开源
珊瑚海
除了不支持组件的动态更新之外,在跨端支持、性能、内置的布局组件等方面和 Tangram 相差不大。同时属于内部团队持续维护,具备全套的开发组件 (可拖拽低代码前端、管理后台)
分别查看 Native 原生、Yoga、Tangram 在同一列表样式中的 fps 数据:
![](https://andrdoc.58corp.com/58app/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/App%E5%B7%A5%E5%8E%82/%E7%8F%8A%E7%91%9A%E6%B5%B7%E5%BC%80%E6%BA%90%E5%85%B1%E5%BB%BA/images/dynamic_layout_fps_cmps.jpg)
丢帧数和丢帧率结果为:
Tangram(3.87%) > Native(2.30%) > Yoga(1.43%)
再对比一下 Native 原生、Yoga、Tangram 在同一列表样式中过度绘制数据:
![](https://andrdoc.58corp.com/58app/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/App%E5%B7%A5%E5%8E%82/%E7%8F%8A%E7%91%9A%E6%B5%B7%E5%BC%80%E6%BA%90%E5%85%B1%E5%BB%BA/images/dynamic_layout_overdraw_cmps.jpg)
可以看到 Yoga、Tangram 因为都做了扁平化处理,所以在过度绘制方面表现不错。
3.客户端引擎
介绍客户端引擎设计时,我们先来看下珊瑚海整体架构:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_dynamiclayout_WebHome_shanhuhai_framework.jpg)
3.1 客户端引擎架构图
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_cc.jpg)
3.2 DSL 设计
- 基础组件:Text,Image, View,List,ViewPager,Span
- ⾃定义组件:轮播头图,titleBar
- 基础 Action:setPropsById,condition, JSEval …
- ⾃定义 Action:invokeApi, jump, sendLog,getLocalData …
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_dsl.jpg)
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_dsl_node.jpg)
示例:
{
"node": {
"name": "View",
"id": "700-003",
"layout": {
"height": "100%",
"width": "100%",
"flexDirection": "column",
"alignItems": "center",
"justifyContent": "center"
},
"style": {
"backgroundColor": "#ffffff"
},
"child": [
{
"name": "View",
"id": "700-0017",
"layout": {
"width": "100%",
"height": "50",
"flexDirection": "column",
"alignItems": "center",
"justifyContent": "center"
},
"style": {
},
"child": [
{
"name": "View",
"id": "700-0031",
"layout": {
"width": "100%",
"flexDirection": "row",
"alignItems": "center",
"justifyContent": "center"
},
"child": [
{
"name": "Image",
"id": "700-0039",
"layout": {
"width": "28",
"height": "28",
"marginLeft": "8"
},
"props": {
"url": "https://pic3.58cdn.com.cn/nowater/fangfe/n_v2a5955cca5b41421a87cbc06261fb7290.webp"
},
"event": [
{
"name": "onClick",
"action": [
{
"type": "Action",
"value": "goBack",
"params": [
{
"type": "String",
"value": {
}
}
]
}
]
}
]
}
]
},
"api": [
{
"name": "communityInfo",
"method": "GET",
"url": "https://api.anjuke.com/community/info"
}
],
"lifeCycle": {
"onCreate": []
}
}
3.3 DSL 引擎
布局
基于 Flexbox 语法(弹性布局,跨端),Yoga(RN 使用的渲染引擎)渲染,高性能,底层 C++;扁平化
数据绑定:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_databinding.jpg)
⾃定义 Action
注册到 ActionManager,继承 BaseAction,注册/静态类⽅法
逻辑动态
集成轻量级 QuickJS 引擎,Action: JSEval(script, params…)
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_logic.jpg)
3.4 全新的移动端 UI 开发模式
传统的移动端开发 UI 一般分为以下几步:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_static_dsl1.jpg)
从流程中可以看出,传统的开发模式存在以下几个问题:
- Android & iOS 需要对一份 UI 设计在对应平台分别进行开发
- 单平台开发时,也存在重复输入,每一个 UI 都需要对应编写视图描述文件、数据实体、数据解析、适配器绑定 UI 数据等逻辑
使用布局动态化开发 UI 的方案优点:
- 跨端支持,支持 Android & iOS,同一份 UI 只需要编写一份 DSL 文件即可在两端运行
- DSL 文件支持数据绑定能力,无需重复编写视图查找、数据实体、数据解析、绑定的代码
- 如果不考虑动态更新问题,也可以将 DSL 文件内置在移动端本地来解决本文章提到的问题
但在动态布局方案中,强调的更多是布局的动态化,其加载、解析 DSL 存在部分耗时:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_static_dsl2.jpg)
以 500行的 DSL 文件为例,在中高端手机运行时加载 + 解析文件耗时达到 70ms(其实这个过程和原生相差不大,原生的优势在于系统 AOT 的加持)
如果不考虑动态化,只是作为内置型应用场景,如何优化此部分性能呢?
编译期提前将 DSL 文件转换成原生代码,省去加载、解析的时间,同时又可以更多地享受系统 AOT 的加持,缺点就是 dex 变大, 加长 classloader 加载时间
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_static_dsl3.jpg)
这边转换的是只是 DSL 对应的 JSON 对象的代码,而没有转换 JSON 对应的每个视图的代码,主要是因为更灵活,无需重复编写 DSL 运行时解析视图的代码,且 DSL 解析成 JSON 对象后,对应的构建 View 等操作和原生差异不大。
实验数据,同样的 DSL 文件,JIT 模式优化到 8ms, AOT 模式优化到 1ms.生成的代码示例:
class RevertToJsonTest {
/**
* output:
* {"node":{"layout":{"alignItems":"center","flexDirection":"column","width":"100%","justifyContent":"center","height":"100%"},"name":"View","style":{"backgroundColor":"#ffffff"},"id":"700-003"},"api":[{"method":"GET","name":"communityInfo","url":"https://api.anjuke.com/community/info"}],"lifeCycle":{"onCreate":[]}}
*
* Test on mobile: load and parse json 80ms, revert map to json: JIT 6ms, AOT 1ms, save 92% - 98%
*/
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
Map<String, Object> resultMap = new HashMap<>();
Map<String, Object> node17645087271206Map = new HashMap<>();
resultMap.put("node", node17645087271206Map);
Map<String, Object> layout17645087328278Map = new HashMap<>();
node17645087271206Map.put("layout", layout17645087328278Map);
layout17645087328278Map.put("alignItems", "center");
....
_17645091636381Map.put("style", style17645091785331Map);
style17645091785331Map.put("color", "#0B0F12");
....
_17645091636381Map.put("id", "700-00244");
_17645093309193Map.put("layout", layout17645093317330Map);
layout17645093317330Map.put("marginRight", "16");
....
_17645093309193Map.put("name", "Text");
Map<String, Object> style17645093400202Map = new HashMap<>();
_17645093309193Map.put("style", style17645093400202Map);
style17645093400202Map.put("color", "#0B0F12");
style17645093400202Map.put("fontSize", "16");
_17645093309193Map.put("id", "700-00389");
Map<String, Object> props17645093441338Map = new HashMap<>();
_17645093309193Map.put("props", props17645093441338Map);
props17645093441338Map.put("text", "区别于组件,模版指的是可复用的DSL代码段,是现有DSL组件能力的组合和复用");
Map<String, Object> _17645093462008Map = new HashMap<>();
child17645090142087Array[14] = _17645093462008Map;
Map<String, Object> layout17645093470302Map = new HashMap<>();
_17645093462008Map.put("layout", layout17645093470302Map);
layout17645093470302Map.put("marginRight", "16");
....
_17645093462008Map.put("name", "Text");
Map<String, Object> style17645093573580Map = new HashMap<>();
_17645093462008Map.put("style", style17645093573580Map);
style17645093573580Map.put("color", "#0B0F12");
....
_17645093462008Map.put("id", "700-00408");
Map<String, Object> props17645093625570Map = new HashMap<>();
_17645093462008Map.put("props", props17645093625570Map);
props17645093625570Map.put("text", "珊瑚海Bundle DSL描述文件");
Map<String, Object> _17645093647561Map = new HashMap<>();
child17645090142087Array[15] = _17645093647561Map;
Map<String, Object> layout17645093656085Map = new HashMap<>();
_17645093647561Map.put("layout", layout17645093656085Map);
....
_17645093647561Map.put("name", "Text");
Map<String, Object> style17645093736060Map = new HashMap<>();
_17645093647561Map.put("style", style17645093736060Map);
style17645093736060Map.put("color", "#0B0F12");
style17645093736060Map.put("fontSize", "16");
_17645093647561Map.put("id", "700-00430");
Map<String, Object> props17645093779067Map = new HashMap<>();
_17645093647561Map.put("props", props17645093779067Map);
props17645093779067Map.put("text", "指的是包含珊瑚海Bundle DSL描述、版本、依赖视图组件版本等信息的JSON文件,需要随珊瑚海Bundle DSL一起上传平台");
Map<String, Object> _17645093807173Map = new HashMap<>();
child17645090142087Array[16] = _17645093807173Map;
Map<String, Object> layout17645093816175Map = new HashMap<>();
_17645093807173Map.put("layout", layout17645093816175Map);
layout17645093816175Map.put("marginRight", "16");
....
_17645093807173Map.put("name", "Text");
Map<String, Object> style17645093952708Map = new HashMap<>();
_17645093807173Map.put("style", style17645093952708Map);
style17645093952708Map.put("color", "#0B0F12");
style17645093952708Map.put("fontSize", "16");
style17645093952708Map.put("fontWeight", "bold");
_17645093807173Map.put("id", "700-00449");
Map<String, Object> props17645094058650Map = new HashMap<>();
_17645093807173Map.put("props", props17645094058650Map);
props17645094058650Map.put("text", "珊瑚海Bundle DSL版本映射表");
resultMap.put("lifeCycle", lifeCycle17645094899247Map);
Object[] onCreate17645094910216Array = new Object[0];
lifeCycle17645094899247Map.put("onCreate", onCreate17645094910216Array);
// new JSONObject by map
JSONObject jsonObject = new JSONObject(resultMap);
System.out.println("RevertToJsonTest revert cost time: " + (System.currentTimeMillis() - startTime));
System.out.println("map revert to json: \r\n: " + jsonObject.toJSONString());
}
}
4. 管理后台
4.1 一站式全链路闭环
平台管理 -> 低代码前端 -> 各端引擎,一站式开发部署上线
多平台、多端
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b1.jpg)
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b2.jpg)
打通低代码前端
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b3.jpg)
快速上线发布
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b4.jpg)
4.2 业务服务可配
各业务可接入管理平台 API,部署自己的 DSL 服务,保证高流量、高并发请求。
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b5.jpg)
4.3 一份 DSL,多端复用
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_mutli_platforms.jpg)
基于 DSL 文件级别的复用,项目管理分开,做到复用的核心为多端引擎的对齐,引擎的向下兼容性。
优点:
- 移动端、小程序、h5 版本节奏不一致,分开管理灵活度高。出现问题方便回滚,不会牵一发动全身。
- 平台版本、引擎版本、DSL 版本逻辑复杂,揉合在一起系统会非常复杂难以管理。这样设计同时可减少后端复杂度,出现问题易排查。
- 后台预留了直接上传的入口,开发工作量可节省。
缺点:增加 DSL 管理、上线的工作量。
4.4 插拔式组件库
插拔式组件库,严苛地版本管理
业务可以定制自己的组件库,并进行版本迭代,在编辑 DSL 文件时,会根据版本规则匹配可用的组件库:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b7.jpg)
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b6.jpg)
低代码前端动态加载对应组件库:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b8.jpg)
4.5 共建共享型模版
类比应用市场主题,大家可以分享自己的 DSL 模版,一起快速构建美观的视图
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_b9.jpg)
5. 低代码前端
5.1 架构设计
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_lowcode_design.jpg)
其中低代码平台负责:
- 加载组件库
- 拖拽、鼠标事件
- canvas 绘制(布局、位置、margin、padding)
- 代码编辑
- 操作历史记录
- 模版管理
- 生成 dsl
组件库负责:
- 拥有哪些组件,每个组件的属性、绘制,和端侧引擎同步迭代
5.2 功能拆解
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_lowcode.jpg)
6.打造更易用的组件库
接入方可以按照规范开发自己的组件库,目前我们厂商业务正在开发一款更通用、更易用的组件库,完成后将共享给更多业务使用:
![](https://wos.58cdn.com.cn/pQnMlKjpQSW/iwikibucket/v1.1_wxpt_wuxian_独立项目_App工厂_Android-App工厂_金盾图片_coralsea_WebHome_coralsea_componets_design.jpeg)
组件说明:
# | 组件名称 | 描述 |
---|---|---|
1 | View | 容器 |
2 | Image | 图片 |
3 | Link | 链接 |
4 | Text | 文本 |
5 | TextEditor | 文本输入框 |
6 | Span | 图文混排 |
7 | RadioButton | 单选按钮 |
8 | RadioGroup | 单选按钮组 |
9 | CheckBox | 复选按钮 |
10 | Switch | 状态切换按钮 |
11 | List | 列表,需要配合 ListGridItem 使用,支持多 item 样式 |
12 | LoopList | 循环列表,需要配合 ListGridItem 使用,适合固定 item 样式 |
13 | GridView | 网格视图,需要配合 ListGridItem 使用,支持多 item 样式 |
14 | ListGridItem | List/Grid item 视图 |
7.生态规划
- 完成 H5、小程序端引擎
- 推广全新的列表/卡片 UI 开发模式
- 低代码平台支持开源项目 Fair 的 DSL 编辑,打造大前端生态