今天给大家带来的是一个使用 JSON 数据来进行页面搭建的工具 juggle
此项目是基于公司内部一个开发工具重新整理并开源的。
目前功能还不是特别完善,但是基本的渲染引擎可以正常工作。
先看一个演示的 demo,你所看到的都是通过JSON渲染而成:
juggle.isjs.cn/report.html…
GitHub
起源:
内部在上线此工具之前我们的工作方式比较原始,当有新需求过来,就基于统一的项目模板进行开发,已有组件如果满足需求,将代码 Copy 到新页面进行开发。 即使两个页面有 90% 相似,都需要从头开始开发,开发时间包含了找组件,调试组件,对接新数据,自测等环节,乐观情况下开发时间也在3个小时左右。开发完成后交由QA同学按照新页面来进行测试,测试时间也需要4个小时。也就是一个页面的复制 + 修改 + 测试的时间就需要1天。 这样的开发速度面对极其频繁的需求迭代时,比如 ABtest 多需求上线,一天上线 5+ 个需求,就会出现瓶颈,增加人力也不能有质的提高。 最早 CTO 提出的解决方案是参考大数据平台的报表渲染页面,将页面组件化,模板化,实现页面的灵活配置、搭建。 最终目标是能实现页面的可视化拖拽布局,将一些简单需求交给 PM 或者运营。 工具上线后的效果很好 ,如果全部都是已有组件的化,搭建一个页面只需要10分钟,算上自测30分钟就可以提测。因为都是已有组件,所以测试只需要简单的进行验证即可。 这样一来整个开发周期缩短到了1个小时,并且达到了组件管理、复用的目的。
方案:
首先明确目标,为什么这么做:
- 减少重复开发成本,多个页面,多个项目共有的自定义组件,需要有一套公共的仓库来进行维护。
- 将简单工作交给PM或者运营。
- 提高开发效率,以往做一个新页面的开发时间,使用配置生成只需要10分钟。
- 提高测试效率,组件未升级的情况下不需要进行深度测试,只需要简单的冒烟即可,并且方便未来集成E2E测试。
在确定了整体方向后,我们进行了技术选型,与需求高度相似的是阿里的飞冰。但因为飞冰的物料开发和想象中的不太一样,最终放弃了。 我认为的物料应该是一个非常灵活的元素,我可以基于已有的组件库进行二次封装,也可以从头开始开发组件。所以我们决定按照自己的理解来新开发一套工具。 物料内部维护,在页面中动态使用物料进行页面搭建,在一个基础页面上承载多个页面,使页面配置化。
明确了目标之后再来明确第一版本要实现的目标,抽象的看我们日常开发的页面,可以分为以下几类:
- 活动页 特点是动画样式丰富。
- 录入页 特点是表单校验,输入项校验。
- 回显页 特点是请求单向,没有用户操作。
- 落地页 特点是入口多,方案多,交互少。
正好最近双十一,各个电商平台的各种活动页,主会场,分会场,品牌落地页特别多。 此次开源的工具是以此为目标,实现落地页的快速配置搭建。
落地页由不同的组件搭建而成,按照组件用途分为以下三类:
- collection 容器级别组件,例如:下拉列表容器,展开收起容器,tab切换容器,侧边栏容器等
- block 块级别组件,用来展示数据的最小单元,例如:多行内容块,左右两列内容块, flex等分内容块等
- public 公共组件,例如:全局的提示窗,全局的页头页尾,全局的loading等
再来思考一个问题,灵活的另一面是规范,如果一个页面可配置,就要满足以下要求,我称之为约定:
- 同一个位置有可能放置任意组件,要求所有组件接受相同的参数。
- 基于第一点,要求每个组件对 prop 参数的要求应该是统一的。
- 组件之间应该有层级关系,容器级别组件(collection)拥有承载块级组件(block)的能力,并且容器之间可以嵌套。
- 容器组件应该拥有自主获取数据的能力,例如三个tab标签切换时,每个tab都对应单独的接口以及列表。
页面的规则制定好之后我们要考虑页面数据的规范,我们把页面数据分为两类:
- 页面布局数据,第一部分是什么组件,包含什么组件,要有一个返回布局数据的源
- 页面业务数据,还是那个原则,可复用的前提是规范,我们与后端约定接口保持最简单的数据结构,保证其复用性。
想清楚以上内容后,再来看看实际的实现方式.
开发步骤:
目标明确,场景明确,开始项目技术栈的确定, 开发环境使用了改造后的 @Vue/cli 4.0
此项目不依赖任何 Vue 组件库,我为了尽快完成demo,使用了有赞的 vant 库。
页面模板的载体是 report.html 页面。用来承载所有页面配置。
页面模板文件为一个 JSON 文件,位于 public/pageConfig 目录下,以 config 开头的js文件。
通过 script 标签异步引入,配置参数挂载到 window.pageConfig 中,再通过 Vue 实例向下传递。
当然你可以使用接口而不是使用文件,我这么做的目的是让配置的维护更方便简单。
每次接触到新需求时,应该尽可能抽象出来成为独立组件,不论是从提高开发效率的角度还是提高测试效率的角度看,这么做都是必要的。 juggle工具不关注组件,只关注结构。所以你可以直接引入组件库的组件,也可以基于组件库二次开发封装一个新的组件。 所有组件位于 /src/components 目录下。按照组件类型区分为block,container,public。 在对应目录下新增组件文件即可完成新组件的开发。 第二步将新组件注册到 /src/htmls/main/report.js 入口的mixin中。 简单两步就可以在配置中使用该组件了:
{
"templateId": "BlockFlexBox",
"prop": {
"dataKeyChain": "bannerList",
"styleOptions":{}
},
"childItem": []
}
复制代码
要注意,juggle的结构对组件的prop进行了约定,所有组件只接受 prop,childItem,baseData 三个参数。 prop: 包含所有内部变量 childItem: 包含所有子组件,按照顺序渲染 baseData: 全局数据 也就是说,新组件的所有参数都要包含在 prop 下,在组件内部进行拆解。
本地运行:
clone 此项目,依次执行以下命令
$ npm install
$ npm run serve
复制代码
打开页面即可查看:http://localhost:8080/report.html?pageCode=0001
开源合作:
项目目前只是一个简单的渲染工具,我希望它未来应该是一个功能更强大,配置更灵活的开发工具。 目前能想到还未实现的大功能点如下:
- 静态配置文件的防缓存
- 组件的按需打包,按需加载
- 全局状态的约定以及管理
- 拖拽布局后台实现
- 复交互类型页面的配置 要实现以上功能,凭借个人力量需要长时间的整理分析,并且独立维护思路单一会考虑不全面。 所以在这里邀请各位参与到此开源项目的维护中。只需要Fork到自己的仓库下,将功能点实现后提交PR给我即可。参加开源项目的同学,会被列入到项目的人员列表中。