在软件开发中,研发效率永远是开发人员不断追求的主题之一。于公司而言,在竞争激烈的互联网行业中,产出得快和慢也许就决定着公司的生死存亡;于个人而言,效率高了就可以少加班,多出时间去提升自己、发展爱好、陪伴家人,工作、生活两不误。
提升效率的途径,无外乎就是「方法」和「工具」。以一个开发者的思维来想,就是将工作内容进行总结、归纳,从一组相似的工作内容中提炼共同点,抽象出解决这一类问题的方法,从而造出便于在今后的工作中更为快速解决这类问题的工具。这个「工具」可以是个函数、组件、中间件、插件,也可以是 IDE、其他开发工具的扩展,甚至是语言。
在现代前端开发中,如果去问一个业务前端开发:「如何提升团队开发效率?」对方所回答的内容中,极有可能会出现「组件库」。没错,在前端工程化趋近完善的今天,在近几年 react、vue 等组件化库/框架的影响下,面向组件开发的思维方式早已深入人心。
现在,组件库已经是一个前端团队的必备设施了,长远来看,团队一定且必须要有自己的组件库。开源的第三方组件库再好,对于一家企业的前端团队来说也只是短期用来充饥的,因为它们无法完全满足一家公司的业务场景,并且出于多终端支持的考虑,必定要进行二次开发或者自研。
组件库有了,团队和公司中推广的效果也不错,绝大多数的人都在用。使用组件开发页面相对 jQuery 时代要每块功能区都得从 <span> 、 <div> 等 html 标签码起来说确实提升了效率,然而有限;要搞出页面需要反复去引入组件,然后组合拼装出来,就像工厂流水线上的工人拼装零件,仍然要去做很多重复动作。
只要觉得当前的开发方式重复的动作多了,就代表还能继续提效,得想个法子减少重复无意义动作。
面向组件的开发方式,是现代前端页面开发提效的初级阶段,也是一个团队所要必经的阶段。
在之前写的文章中有段话——
组件可以很简单,也可以很复杂。按照复杂程度从小到大排的话,可以分为几类:
对,不用揉眼睛,你没有看错!
站在更高的角度去看,「页面」和「应用」也是一种「组件」,只不过它们更为复杂。在这里我想要说的不是它们,而是「基础组件」和「复合组件」。
文中提到了「页面」和「应用」也可以看作是种「组件」。虽然与当时的想法有些差异,但本文的内容就是要在那篇文章的基础上简单聊聊在「页面」层面的提效。
一般来说,「页面」是用户所能看到的最大、最完整的界面,如果能在这个层面有个很好的抽象方案,在做业务开发时与单纯地面向组件开发相比,应该会有更大的提效效果。
GUI 发展了几十年,人机交互的图形元素及布局方式已经相对固定,只要不是出现像 Google Glass 之类的革命性交互设备,就不会发生重大改变。在业务开发中界面形式更是千篇一律,尤其是 web 页面,尤其是中后台系统的 web 页面,一定可以通过什么方式来将这种「千篇一律」进行抽象。
试着来回想下,自己所做过的中后台系统的绝大部分页面是不是我所描述的这样——
页面整体是上下或左右布局。如果是上下布局的话,上面是页头,下面的左侧可能有带页面导航的侧边栏,或者没有侧边栏直接将页面导航全部集中在页头中,剩余区域是页面主体部分,承载着这个页面的主要数据和功能;如果是左右布局,左侧毋庸置疑就是有页面导航的侧边栏,页头跑到了右侧上面,其余是页面主体。
中后台系统的主要功能就是 CRUD,即业务数据的增删改查,相对应的页面展现及交互形式就是列表页、表单页和详情页。列表页汇总了所有业务数据的简要信息,并提供了数据的增、删、改和更多信息查看的入口;表单页肩负着数据新增和修改的功能;详情页能够看到一条业务数据记录最完整的信息。
每新增一个业务模块,就要又写一遍列表页、表单页和详情页……反复做这种事情有啥意思呢?既然这三种页面会反复出现,那干脆封装几个页面级别的组件好了,有新需求的时候就建几个页面入口文件,里面分别引入相应的页面组件,传入一些 props ,完活儿!
这种方式看起来不错,然而存在几个问题:
我需要一种既能看一眼就理解内容结构和关系,又具备较好扩展性,还能减少重复代码和无意义动作的方式——是的,兜了一个大圈子终于要进入正题了——面向模板开发。
面向模板的前端开发有三大要素:模板;节点;控件。
我所说的「模板」的主要作用是内容结构的描述以及页面的配置,观感上与 Xhtml 相近。它主要具备以下几个特征:
为什么不选择用 jsON 或 jsX 来描述和配置页面?因为模板更符合直觉,更易读,并且中立。用模板的话,一眼就能几乎不用思考得看出都有啥,以及层级关系;如果是 JSON 或 JSX,还得在脑中进行转换,增加心智负担,并且拼写起来相对复杂。vue 上手如此「简单」的原因之一,就是它「符合直觉」的设计。
要使用模板去描述页面的话,就得自定义一套具有抽象语义的标签集。
页面的整体布局可以用如下模板结构去描述:
<layout>
<header>
<title>欧雷流</title>
<navs />
</header>
<layout>
<sidebar>
<navs />
</sidebar>
<content>...</content>
</layout>
<footer>...</footer>
</layout>
看起来是不是跟 HTML 标签很像?但它们并不是 HTML 标签,也不会进行渲染,只是用来描述页面的一段文本。
整体布局可以描述了,但承载整个页面的主要数据和功能的主体部分该如何去描述呢?
在上文中提到,我们习惯将中后台系统中与数据的增删改查相对应的页面称为「列表页」、「表单页」和「详情页」。虽然它们中都带有「页」,但真正有区别的只是整个页面中的一部分区域,通常是页面主体部分。它们可以被分别看成是一种视图形式,所以可以将称呼稍微改变一下——「列表视图」、「表单视图」和「详情视图」。一般情况下,表单视图和详情视图长得基本一样,就是一个能编辑一个不能,可以将它们合称为「表单/详情视图」。
「视图」只描述了一个数据的集合该展示成啥样,并没有也没法去描述每个数据是什么以及长啥样,需要一个更小粒度的且能够去描述每个数据单元的概念——「字段」。这样一来,用来描述数据的概念和模板标签已经齐活儿了:
<view>
<field name="name" label="姓名" />
<field name="gender" label="性别" />
<field name="age" label="年龄" />
<field name="birthday" label="生日" />
</view>
虽然数据能够描述了,但还有些欠缺:表单/详情视图中想将字段分组展示没法描述;对数据的操作也没有描述。为了解决这两个问题,再引入「分组」和「动作」。这下,表单/详情视图的模板看起来会是这样:
<view>
<group title="基本信息">
<field name="name" label="姓名" />
<field name="gender" label="性别" />
<field name="age" label="年龄" />
<field name="birthday" label="生日" />
</group>
<group title="宠物">
<field name="dogs" label=":dog:" />
<field name="cats" label=":cat:" />
</group>
<action ref="submit" text="提交" />
<action ref="reset" text="重置" />
<action ref="cancel" text="取消" />
</view>
模板很好地解决了内容结构描述和配置的问题,但如何去动态地调整结构和更改配置呢?在平常的业务页面开发时也许不会太凸显出问题,但碰到流程表单设计或页面可视化编辑这种灵活性很高的需求时,问题就会被暴露出来了。
在这里,我要将定义好的标签集所拼成的模板解析成节点树,通过更改树的结构和节点的属性去影响页面最终的呈现效果。每个节点都会有节点的基本信息、对应标签的属性和一些节点操作方法:
{
name: "field",
tag: "field",
attrs: {
name: "name",
label: "姓名"
},
parent: {},
children: [],
remove: function() {},
insert: function() {}
}
在页面模板化且节点化之后,理想情况下,页面长啥样已经不受如 react、Vue 等运行时技术栈的束缚,控制权完全在解析模板所生成的节点树上,要想改变页面的视觉效果时只需更改节点即可。
广州设计公司https://www.houdianzi.com 我的007办公资源网站https://www.wode007.com
页面内容的描述通过模板来表达了,页面内容的控制权集中到节点树中了,那么页面内容的呈现在这种体系下应该如何去做呢?负责这块的,就是接下来要说的面向模板开发的第三大要素——控件。
「控件」这个词不新鲜,但在我所说的这个面向模板开发的体系中的含义,需要被重新定义一下: 「控件」是一个可复用的,显示的信息排列可由用户改变的,可以进行交互的 GUI 元素。
在这个面向模板开发的体系中,模板和节点树完全是中立的,即不受运行时的技术栈所影响;而控件是建立在运行时技术栈的基础之上,但不必限于同一个技术栈。也就是说,可以使用 React 组件,也可以用 Vue 组件。
每个控件在使用前都需要注册,然后在模板中通过 widget 属性引用:
<view widget="form">
<group title="基本信息" widget="fieldset">
<field name="name" label="姓名" widget="input" />
<field name="gender" label="性别" widget="radio" />
<field name="age" label="年龄" widget="number" />
<field name="birthday" label="生日" widget="date-picker" />
</group>
<group title="宠物" widget="fieldset">
<field name="dogs" label=":dog:" widget="select" />
<field name="cats" label=":cat:" widget="select" />
</group>
<action ref="submit" text="提交" widget="button" />
<action ref="reset" text="重置" widget="button" />
<action ref="cancel" text="取消" widget="button" />
</view>
这样,一个面向模板开发的普通表单页出来了!
面向模板的开发方式很好,能够大幅度提高业务前端开发效率,一定程度上减少了业务系统的搭建速度;作为核心的模板和节点树是保持中立的,大大降低了运行时技术栈的迁移成本,且能够应对多端等场景。
面向模板的开发方式初期投入成本很高,标签集、模板解析和控件注册与调用机制等的设计和实现需要较多时间,并且这仅仅是视图层,逻辑层也需要做出相应的变化,不能简单地用 props和事件绑定进行处理了。
这个体系建成之后,在业务开发上会很简单,但机制理解上会增加部分开发人员的心智负担。
为了效率,一家公司里的业务前端开发到最后一定是面向模板,而非面向组件。
原文:https://www.cnblogs.com/Qooo/p/13816893.html