摘要:如何快速、高效地构建前端组件乃至页面是解放前端生产力的重要标志,掌握抽象组件和页面模型,理解前端可视化搭建思路,摆脱固有的开发模式,提升前端开发效率,是每位前端应该了解的。
本文分享自华为云社区《【云驻共创】前端可视化框架是怎样炼成的?》,原文做者:华为云EI专家胡琦。html
随着移动互联网的迅猛发展和 5G 技术的普及,前端页面需求量爆炸增加,用户交互也变得愈来愈复杂,页面从零开发的成本也水涨船高。如何快速、高效地构建前端组件乃至页面是解放前端生产力的重要标志,掌握抽象组件和页面模型,理解前端可视化搭建思路,摆脱固有的开发模式,提升前端开发效率,是每位前端应该了解的。前端
在咱们前端开发过程当中可能常常这样会遇到这样的场景:ios
(某天,产品经理找到前端。) 产品经理:简单开发一个欢迎页面,就展现下“欢迎访问”。 (这没什么难度啊,代码很好写了,因而前端不假思索就把代码秀出来。) 前端: ``` <template> <div> 欢迎访问 </div> </template> ``` (一天以后,产品经理以为这个欢迎词不够具体,还想加个主语,因而……) 产品经理:那个欢迎词简单改一下,改为“欢迎访问咱们的网站”。 前端: ``` <template> <div> 欢迎访问咱们的网站 </div> </template> ``` (通过代码提交、代码审核、代码合并、部署到测试环境、测试验证、灰度发布、产品验证、 发布上线等一系列流程,欢迎词终于更新了…… 又一天后,产品经理以为欢迎词没有展示出咱们的优点,因而加了个形容词来描述咱们的网站。) 产品经理:那个欢迎词仍是不行,改为“欢迎访问咱们帅气的网站”。 (迫于产品经理手中40米长大刀的威慑,尽管心中尽是问号,前端仍是修改了代码。) 前端: ``` <template> <div> 欢迎访问咱们帅气的网站 </div> </template> ``` (又又一天后,产品经理想到一个“狂拽酷炫”的形容词,因而……) 产品经理:欢迎词再改下,改为“欢迎访问咱们狂拽酷炫的网站”。 (此时,前端坐不住了,想到了经过让产品经理本身维护JSON文件,在页面中获取JSON中title字段进行渲染显示) 前端: ``` <template> <div> {{title}} </div> </template> <script> import axios from "axios"; export default { data() { return { title: '' } }, created() { this.queryTitle() }, methods: { queryTitle() { axios.get('JSON文件所在路径').then(res=>{ if(res && res.status === 200) { this.title = res.data.title } }) } } } </script> ``` (又又又一天后,产品经理有了另外一个想法,此次不是改欢迎词了。) 产品经理:我想再加一个选择框,用来收集用户信息。 (此时,一阵风吹过,前端在风中凌乱了……)
固然,既然能想到经过 JSON 去配置,那意味着整个组件、页面都能配置,只需给到产品经理一个可视化的界面去配置,便可生成 TA 想要的页面,大大节省了沟通成本、提高了开发效率。这时,可视化框架应运而生。axios
可视化框架是怎样的?首先咱们先了解一下可视化框架的构成和分工。开发做为可视化框架的维护者,能够提供一个可视化的配置平台;目标受众,也就是可视化平台的使用者,如上文例子中的产品经理;使用者经过可视化配置平台对页面进行配置,平台会产出一份配置文件用来描述页面并上传到存储空间;配置文件经过渲染引擎解析最终生成页面。在这个构成中,做为开发框架的维护者,咱们只须要关注可视化配置平台和渲染引擎,固然可视化配置平台也只是将使用者的输入转化为渲染引擎能解析的配置文件并上传,是锦上添花的一环,若是还想应用在更复杂的场景,还能够加上权限管理,好比 A 只能编辑 A 负责的页面,B 只能编辑 B 复制的页面,还能够实现一个工做流的流程编排,好比审核……框架
可视化框架的核心在于渲染引擎,咱们如何得出这个渲染引擎以及渲染引擎是如何运做并渲染最终的页面,是咱们所关心的。如何得出渲染引擎就不得不先说说页面泛化模型。布局
为何会有页面泛化模型?由于咱们不一样的页面实际上是经过渲染引擎解析不一样的配置文件渲染出来的,所以渲染引擎须要泛化的能力。好比页面 A 是表单填写,那么就会要求渲染引擎可以解析表单的配置文件;好比页面 B 包含卡片式列表,就会要求渲染引擎可以解析列表的配置文件。页面泛化模型的创建,主要根据开发者自身的经验和方法创建知足自身业务需求的模型便可。像上文案例中,若是产品经理一直只要求修改欢迎词,那案例中的那段 title 的渲染引擎就足够知足需求了。接下来,以华为云官网页面为例,抛砖引玉讲讲页面泛化模型如何创建。测试
从上面截图中咱们能够看出这实际上是一个从上到下的结构,能够理解为页面是由一个个楼层构成的,楼层能够理解为body下的一个div块,或者是一个功能块。好比图中从上到下是页头、banner、引导跳转楼层、推荐文章、技术领域楼层。固然咱们常常遇到的页面也不全都是上下结构,还有左右结构。flex
其实,像这样左右结构的页面,您能够理解外层还有一个更大的容器组件包裹,总体造成一个楼层。容器组件只负责样式,好比上图中容器组件负责左右布局,若是您对布局尚未概念,您可按下F12键查看上图布局的代码,您会看到其实左边两个模块是被classname为edu-index-version-left的div包裹,右边两个模块是被classname为edu-index-version-right的div包裹,它们依旧是从上到下的楼层。所以,页面 = 楼层 + 容器组件。网站
再来看看楼层解构,以上图为例,图中主体部分是一个tab功能组件,经过查看页面源码,咱们发现两处红色框圈出来的文本并无设计在tab功能组件里,而是单独成为文本控件,这是由于这部分是属于定制化的功能,并非每一个tab功能组件都有的,就抽离出来了遵循单一职责原则,蓝色框是一个容器组件。再来看看tab功能组件中的卡片,卡片也是由一个一个的控件组成。所以,楼层=容器组件 +控件。this
可视化框架中的控件和常见的 UI 框架中的组件同样,都具备完善且单一的职责,好比表格组件,不管再怎么加功能都是在表格内部,表格里面的功能是没法拆分出去的。但可视化框架中的控件和 UI 框架中的组件仍是有区别的,主要不一样点在于控件须要用来被编辑,所以它具备统一的props,全部的控件要遵循同样的props,如视图配置和数据源,在可视化中咱们不知道页面会用到哪些组件,所以须要统一去作循环渲染,不感知控件的具体属性。
可视化框架中的容器组件本质上也是组件,主要负责布局,分为基础容器组件和功能容器组件。基础容器组件中左右布局通常经过栅格或者 Flex 实现,上下布局经过正常的文本流或者定位以及控件自身间距等实现。功能容器组件如 tab 容器、轮播组件等。
当考虑用户交互时,事件在可视化模型中就不得不考虑。可视化模型中的事件须要关注交互的发起者、交互的做用者以及交互的影响方式,而不须要关注交互的种类和交互的具体内容。好比点击了某个按钮,步进器的最大最小值从 一、2 变成 三、4,实际上是改变了input控件的min和max属性;好比表格筛选加了必定条件以后,显示数据变少了,是由于触发了数据事件影响了表格的数据源;好比一个开关组件,点击以后控制控件的显示和隐藏……
最终,咱们肯定的可视化模型就是上图中总结的点。可视化页面由控件 + 容器组件 + 事件组成,控件的粒度最小,是功能的最小单位;容器组件负责布局,是样式的集合;事件响应用户交互传递控件间依赖关系。那控件、容器组件、事件是怎么结合的呢?就不得不谈谈渲染引擎了。
渲染引擎本质上也是组件,主要功能是渲染当层组件、处理当层组件交互关系、对当层组件状态进行管理。它不关注子层组件,子层组件由子层容器的渲染引擎渲染,由于每一层组件的配置和数据源不同,所以渲染结果也不相同。视图部分示例代码(基于Vue.js)以下:
<template> <div :class="clsPrefix"> <component :is="component._type" v-for="component in viewConfig.components" v-show="showState[component._id]" :ref="component._id" :key="component._id" :viewConfig="component" :dataSource="dataSource[component._id]" @valueChange="valueChangeHandler($event, component._id)" /> </div> </template>
最外层是由div包裹,使用自定义动态组件component的方式定义渲染引擎,带下划线的属性意味着是自定义组件的内置属性,is决定组件渲染的类型,如button,作到能够不感知当层组件具体内容渲染当层组件;v-for循环当前组件的属性;v-show控制组件是否显示,经过showState进行状态管理;ref创建索引,能够用来作一些高级功能,好比父层容器调用子层容器的方法;viewConfig和dataSource就是上文中提到的控件中所必需的;@valueChange是组件提交的统一事件。
父层容器和子层容器本质都是渲染引擎,只是样式不一样。好比说一个左右布局的容器组件,至关于在视图中v-for循环的地方绑定一个class如栅格布局或者flex布局的样式,若是是栅格布局的话,用户就要先定义type是栅格组件,而后配置viewConfig中grid属性之类的,若是是flex布局,定义的type就是flex组件,对齐方式如指定为space-between之类的。上文中示例代码就是一个正常的从上到下的布局。
首先外层传递两个关键的参数--viewConfig和dataSource,当层容器就会进行配置解析和配置分发。配置解析主要包含属性映射和生成事件,属性映射好比控件自己须要title属性,而配置文件中多是叫label属性,这时咱们要将label转换成title,只不过转换逻辑不包含在渲染引擎中,只是调用外部封装好的方法;生成事件则是根据配置生成预设事件并挂载。在配置分发以前,会先将解析好的配置进行初始化父层状态并存放在父层,主要考虑到viewConfig和dataSource不是同步赋值,须要等待都就绪了才进行分发。
在介绍控件的时候,提到每一个控件都要提交,由于每一个控件都不能成为其余控件的一个origin。好比Tip组件,虽然自己可能没有交互,但可能成为别的控件的依赖项,子层可能须要获取内容,子层容器的提交会被收集在父层容器的valueWatch中,在子层容器提交之后,若是状态变化的话,那父层容器就会根据functionList去循环执行的事件;若是是展现类事件,就会更新父层的showState控制显示或隐藏,若是是数据类事件,则会改变viewConfig和dataSource,对目标进行一个从新赋值。 总得来讲渲染引擎流程就包含以上四个步骤:配置解析、配置分发、收集提交、发起事件。
为了减小页面开发代码量,提高代码复用度,咱们指望页面能进行可视化编辑;为了得出一个经过的可视化框架,咱们对页面进行了可视化建模分析,得出几乎全部的页面均可以由控件和容器组件构成,经过泛化的事件处理用户交互和组件间的级联关系;根据建模的结果创建了渲染引擎,支撑起整个流程,最终实现可视化。
本文整理自华为云社区内容共创活动第二期之【线上直播】2.0倍起步?高效完成前端页面。
查看活动详情:https://bbs.huaweicloud.com/forum/thread-111494-1-1.html