腾讯 Web UI 解决方案 QMUI Web —— 探索与沉淀

2017-09-07 22:59:41 +08:00
 TencentOpen

作者简介: 李浩成( Kayo ),腾讯广州研发部 UI 工程师。

经过长时间的打磨迭代,QMUI Web 作为腾讯广研 QMUI 团队的一个开源项目,正式发布到 Tencent Github。QMUI Web 是一个 Web UI 的解决方案,从零开始,由编码规范,到组件和工具方法的制作,再到工作流的整合,不断在迭代,也不断在优化,走过了不少的路。趁着发布的机会,我们正好回顾这一路的探索过程,分享其中的点滴,也希望能借此让大家更了解 QMUI Web。

背景

2014 年中,QMUI 团队支持的主要项目是 QQ 邮箱,Web 端的邮箱是个庞大的项目,但其并没有统一的 UI 基础库,多年的高速迭代使得项目的 UI 代码变得混乱,各个模块之间各自开发,除了在代码层面表现出混乱和不可控之外,表现层面也并没有很好地统一起来。因此,项目急需一套统一的团队编码规范以及一个 UI 基础库。 恰好,这个时候 Sass 等 CSS 预处理器已经发展成熟,自动化工作流的工作模式也日趋完善,因此,我们决定基于这些技术制作一套通用于不同项目的 Web UI 框架。框架的场景定位很明确:需要控制整体样式,并且可以适应频繁迭代打磨的大型项目。所以,这套即将诞生的 Web UI 框架的特性也很明确:需要方便地控制项目的整体样式,应对频繁的界面变动,并保持项目质量稳健。 此后经过三年的发展,QMUI Web 最终发展为包含编码规范、样式工具方法与样式管理、内置工作流,配套的 GUI 桌面 App,以及拥有完整文档的解决方案。

设计理念

在制作框架的过程中,我们把框架需要的特性进行整理和思考,形成了一套对于该框架的设计理念,在这些设计理念之中,最核心的关键为通用于多个项目高效迭代保持代码稳健,框架的设计也遵循这三个核心点,体现在框架上,具体就是:

而具体到代码层面,则可以归纳为两个方面:

Class-name 命名规范

作为一个 Web UI 框架,编写代码主要是 CSS 与 HTML,而提到 CSS 与 HTML 的编写,首先要处理的是 Class-name 的命名,在过往的开发中,Class-name 的命名并没有固定的规范,开发人员各自进行开发,一个项目经过长时间的迭代后,经常会遇到如命名冲突,命名混乱等问题,这使得项目的迭代变得笨重,也不好维护。因此,我们需要一套具有如下特点的 Class-name 命名规范:

因此,最终 QMUI Web 制定了一套以命名空间为核心的命名方式,这个命名方式主要由“命名空间”,“业务与组件的拆分”,“精确表达 View ”三个部分构成。

命名空间

一个 QMUI Web Class-name 应该包含一个命名空间,也是 Class-name 的开头,如果是业务,则以业务内容为命名空间,如果是公共组件,则全局使用项目的名字(或缩写)为命名空间。如一个名为 Demo 的项目,项目缩写可以是 dm,那么该项目下的项目组件和公共类可以这样命名: dm_btn(按钮)、dm_icon(图标)、dm_ipt(输入框)、dm_toolbar(工具栏)。 逻辑模块命名以具体业务作为前缀,如简历( resume )功能里面的非公共组件部分,以 resume_ 作为前缀(resume_modresume_textresume_list),个人信息( profile )页面的非公共组件部分,则可以以 profile_ 作为前缀(profile_statgeprofile_stage_title)。 命名空间作为一种基础的隔离,把组件与业务,以及不同的业务之间的 Class-name 命名隔离开来,避免冲突,而后父子元素之间逐级展开编写,保证了项目内多人协助不易冲突,同时命名带有语义,也方便理解和阅读。

业务与组件的拆分

接着,QMUI Web 中把项目的代码划分为通用组件(跨项目的组件),项目全局组件(适用于某个具体项目),业务组件(适用于某个业务),以及业务逻辑代码,这样区分出 4 个颗粒度可以使得代码更容易被组织和复用,一个模块随着设计元素迭代,也可以在这 4 个颗粒度之间进行迭代,从而使得模块在迭代时会更加稳健。而 QMUI Web 框架中的组件应该只收纳通用组件,即跨项目组件。

精准表达 View

精准表达 View 是指在命名 DOM 节点时要明确这是一个怎样的 View,这里的 View 指的就是 UI 层面上这个元素表示的含义,常见的场景是,一个命名为 resume_head 的元素,在经历多次迭代后实际在代码中却充当了页脚,这样的命名在多人协作时很容易给后面的开发者造成困扰,而精准表达 View 则要求我们明确一个 UI 元素的含义,并在命名时准确地表达。

基础样式配置与半封装组件

前面的“ Class-name 命名规范”主要是在规范层面上去实践 QMUI Web 的核心理念,而接着更多地就是在代码层面上去实践了,主要包括三点:

半封装组件即面向项目的组件

前文提到,QMUI Web 把组件划分为通用组件,项目全局组件,业务组件三种组件,而 QMUI Web 框架收纳的则是通用组件,也是跨项目的组件,但每个项目的 UI 表现并无关联,如何处理跨项目组件就成为了一个问题。为此,QMUI 在处理组件时采取的是“半封装”的处理方式,QMUI 框架封装的是代码,所谓半封装,即封装那些与项目具体 UI 表现没有必然联系的代码。例如按钮组件,QMUI Web 中只封装了文字居中对齐,鼠标手型,浏览器样式重置,低版本 IE 兼容性处理等代码,而常用的样式如边框、背景、字体表现等,都抽取成变量控制,这些组件的变量最终都汇集到一个配置表 Sass 文件中,配合全局的颜色变量、字体变量等变量,就可以做到跨项目抽取组件,每个新项目只需要关注具体 UI 表现而无需再处理各种常见的 UI 问题,同时方便地通过调整这些变量的值而快速修改整个项目的样式。

组合而不是继承

在处理组件时,继承的方式是指一个组件类承担复杂的功能,而组合的方式则是把组件类拆分成一个基类,以及多个子类,每个子类承担的功能不重复,对于我们的主场景——频繁迭代,保持稳健,显然组合会更加适合,这种方式避免了在频繁的迭代中需要不断修改组件类,每次迭代只需要修改对应的子类即可。

颗粒度

对于组件的抽取,时常要考虑颗粒度的划分,颗粒度本身就是一个比较开放性的问题,在这里与大家分享一些沉淀的经验:

以上便是 QMUI Web 具体的设计理念,通过命名规范、基础样式配置与半封装组件来保证多人协作时的高效率与可维护性,也使得一个 UI 框架能为不同的项目服务。

具体组成

作为一个框架,QMUI Web 主要提供了四种能力来提升 UI 开发的效率与质量,对应前文提到的框架设计理念,QMUI Web 提供的这些功能都是为了帮助开发者方便地控制项目整体样式,应对频繁变动,同时保持代码稳健。

基础配置与组件

前文提到,框架中会有一份配置表,是各种 Sass 的变量,这些变量控制了一个网页基本的字体样式,链接颜色,通用组件的样式配置等基础样式,在创建一个新项目时,应该先根据设计稿配置好这些信息,当这些信息配置完成,那么一个项目的基本样式就可以快速实现了。例如下图中这些配置属于 QMUI 通用配置,通过修改这些配置则可以快速修改项目的字体策略、正文字体大小,链接颜色等 UI 常用的 CSS 属性。

内置工作流

QMUI 中包含一个基于 gulp 的内置工作流,用于快速解决大量重复劳动力的工作,从而提升效率。QMUI 的 gulp 中预先实现了监控 Sass 文件并自动编译和优化,雪碧图处理,模板 include 能力(可以传参和使用条件判断),浏览器自动刷新,图片压缩,文件清理,文件合并以及自动变更等能力。

Sass 增强支持

QMUI 中提供了大量基于 Sass 的 CSS 预处理的方法,包括 CSS Reset,一些常见的 CSS 类(例如清除浮动),计算长度值的简便方法(例如获取 padding 在某个方向的值,计算两个长度值的中间值),快速实现一些样式效果的工具方法(例如实现 border 三角形,适应多倍屏幕的 1px 边框等),这些都是用于提高样式开发的效率和质量。

扩展组件

扩展组件并不是由 QMUI Web 的主源码提供,而是由 Demo 提供,通常是因为这类组件结构较复杂,因此业务性无法很好地剥离,从而不能抽取成公共组件,因此这类组件就放在一个 Demo 页,以参考组件的形式帮助开发。

GUI

我们提供了一个用于管理 QMUI Web 项目的桌面 App,在代码层面它独立于 QMUI Web 的源码。它通过 GUI 界面处理 QMUI Web 的服务开启 /关闭,并提供了编译提醒,出错提醒,进程关闭提醒等额外的功能,在处理多项目,多分支时能更方便地进行开发。

优化和开源

在经历较长时间的迭代后,QMUI Web 也逐渐完善起来,此时我们也开始将 QMUI Web 进行开源。开源意味着 QMUI Web 会进入更加全面的环境中去打磨,在框架的非主体内容如代码规范、注释、文档上面也需要更费心思,考虑的点也需要更加周全。这对团队来说无疑是个很好的机会,可以有更多的渠道审视框架,吸收建议,持续进行优化。

在加入开源的大环境后,我们从 Github、社区论坛中都获取了不少建议,除了 bug 的反馈外,也指出了一些待完善的地方和提出一些优化的解决方案,从而使得 QMUI Web 注入了更多活力,因此我们也逐步进行了如“自动化测试用例”、“ gulp 结构化”,“引入 SassDoc 自动化生成文档”,“编译 Sass 时引入增加更新”等优化,其中不少优化点我们也在项目的 Github Wiki 中进行了详细的分享,有兴趣的用户可以自行浏览。

总结与展望

至此,QMUI Web 发展为现在这套完整的方案,也终于开源到 Github Tencent 与大家分享,我们期望通过开源与大家进行更多的交流,也使得 QMUI Web 进入更加全面的环境中去打磨,形成对代码规范、注释、项目文档感谢公司与部门给我们提供了一个平台,可以在大型项目中经历迭代和沉淀。开源只是一个开始,我们后续仍会不断进行探索和优化,期待更好的 QMUI Web。

关注 QMUI Web, 来 Github 给我们 star 吧!

https://github.com/Tencent/QMUI_Web

查看 QMUI Web 项目源码,请点击[阅读全文]。

7575 次点击
所在节点    请不要再发这样的文章
1 条回复
Nobitasean
2017-09-08 14:39:32 +08:00
阅读全文在哪里

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/389045

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX