Description
总览
近日,开(抄)发(袭)了一个移动web UI组件库,仓库在这儿,目前仍属于半成品,组件的数量和质量都有待提高。在这个过程中我学到了很多东西,特开系列篇记录下来。目前规划的篇章包括:
缘起
为什么想到要开发这样一个东西呢?
因为这个东西是标配啊,没折腾过这个都不好意思说自己做过移动web开发呢!
其实这个东西老早就有人开始做了,比如mint-ui、vux。追寻着大牛们的脚步,让我们来一探究竟。
十万个怎么办
当我开始构思这个东西的时候,有数不清的问题冒进我的脑海,包括但不限于以下:
- 需要抽象常用组件(按钮、输入框、单选、复选)靠,好多啊。。。
- 这东西得做成一个npm包,到时候发布到npm,方便安装使用。
- 组件内部肯定会有一些依赖,如果处理这些依赖?
- 还要考虑用webpack打包
- 我应该怎么设计对外输入接口?也就是说别人用我这个库的时候怎么调用才方便?
- 嗯,我应该去参考一下现有的第三方实现,看看人家是怎么做的
- 用啥语言写好呢?vue还是react?
- 用hammer解决touch延时问题
- 移动端需要normalize这些东西吗?
- icon-font要引入一个吧,用哪个库?
- 大问题:移动端尺寸适配。之前研究过淘宝的flexible,但是好像问题不少,要不考虑一下用flexbox?
- 样式肯定要统一,所以肯定要定义variable.scss、mixin.scss这些文件
- 源码怎么组织
- 要做统一的动画吗?
- 要根据安卓和ios做两套样式吗?
- ……
-------------------------我是晕乎的分割线+_+--------------------------
困境:问题太多,思考毫无逻辑与章法,怎么办?
答案:分层设计,画架构图。架构图更多的意义是帮助思考的过程,而非展示成熟的想法。
当时初步的分层设计如下:
另外,要把握好考虑的复杂度。一开始考虑得太复杂,会让开头寸步难行。一开始考虑得太草率,会让后期面临大的改动。
也要平衡好通用性与针对性。想要更加通用,势必增加开发成本。在一个组件库的前期,更多的技术诉求是降低重复性劳动,提高效率。从这个角度看,应该更加重视针对性。自己团队用得爽再说。
下面说一些关键点。
源码目录组织与第三方调用方式
避免影响全局
写一个库跟写一个应用不同,库是需要到处被调用的。无法预知外部环境,也不应该修改外部环境。从这么几个方面进行考虑。
- 库只创建vue组件构造器,并不注册组件。组件的注册交由第三方来完成。如果库本身组件之间需要相互调用,那么务必采取局部注册的方法。
- 使用babel-runtime,而非babel-ployfill,因为后者会影响全局。参考这里
- 组件类的命名需带上前缀v,样式冲突的概率就很低了,没有必要引入css-module来额外处理。
然而,我还是有一个地方影响了全局,那就是组件库依赖于淘宝的flexible来做适配,这东西改变了html的font-size和页面scale,就好像在js里面修改了全局变量一样。flexible已经是2年前淘宝提出的解决方案,时至今日,它也暴露出一些问题。比如常见的,在页面当中嵌入地图的时候,就会因为scale导致地图缩小的问题。听说天猫已经用flexbox代替flexible了,之后有时间得好好研究一下这个。
不仅仅是input框
之前设想的UI库,大概只想到了一些input、radio、checkbox这些最小的表单相关的组件。但是,这里有两个问题。
第一,还有像toast、alert、dialog这类message组件,也是非常关键的。而且这些组件与普通的组件不同,对它们应该采取插件化的形式来实现,参考这里。
第二,仅仅有input、radio这些孤立的元组件,其实是不能承载业务的。一个孤零零的input框、单选框有什么用呢?一般来说,业务场景常见的表单是可以按照group和cell这两个概念来划分的。如下图,第一个group就包含三个cell。所以,真正意义上的input组件肯定是内嵌在group和cell当中的。所以定义group和cell组件。那么input组件如何嵌入到cell组件当中呢?这样就用到了vue的slot功能。