Press UI — 基于uni-app的跨端组件库
1. 开始
介绍一款基于 uni-app
的跨端组件库——press-ui,也可用于普通H5项目。API 与 vant
一致,可以看作是 uni-app
版本的 vant。
为什么不用uni-ui
或者uview
等组件库呢?有两个原因:
- 我们项目是从H5项目转成
uni-app
项目的,项目比较大,改动成本高。 uni-ui
、uview
这些库的API易用性较差,与vant
相比差距大。
2. 介绍
2.1. 基础介绍
- 70+ 基础组件,覆盖移动端主流场景
- 支持基于
uni-app
的H5、微信小程序、QQ小程序 - 支持普通H5项目
- 零外部依赖,不依赖三方 npm 包
- 提供丰富的中英文文档和组件示例
- 支持主题定制,内置 600+ 个主题变量
- 支持国际化,内置 16+ 种语言包
文档地址:https://novlan1.github.io/press-ui/
三端示例体验地址:
2.2. 解决痛点
press-ui
主要解决了以下痛点:
- 可支持包含
vant
的H5项目平滑迁移至uni-app
项目,只需要改下引用地址和组件名称。 - 丰富的组件类型,以及易用的API,让
uni-app
开发变得简单。 - 支持国际化、主题定制等,组件灵活性更强
同时,将项目中业务组件沉淀到press-ui
中,有以下好处:
- 增强可维护性,提升开发效率
- 通过整理代码,合并属性,分离业务逻辑等,让组件变纯粹,增强可维护性,进而提升效率
- 减少业务和组件的耦合,降低各自复杂度,并减少bug
- 封装核心逻辑,控制变化
- 不用担心外部合作人员改乱代码,以及解决冲突时的覆盖问题
- UI问题定位简单
- 三端代码同时发布,以及多种类型的示例,覆盖面全,容易发现ui问题,以及三端表现不一致问题
- 可提升性能
- 通过自定义队伍数等变量,定位性能瓶颈,并解决性能问题
- 提高可复用性,可应用到其他项目
- 技术沉淀,技术积累,不断打磨组件细节
2.3. 应用场景
press-ui
可应用于uni-app
项目,或者普通的H5项目,目前已应用在王者赛宝、HoK Club、赛宝pro等项目中。
3. 如何使用
3.1. 用于uni-app项目
- 安装npm包
- 在页面中正常引入并使用
比如 message-detail
组件:
- 配置
vue.config.js
注意,需要在vue.config.js
中配置下 transpileDependencies
:
3.2. 用于普通H5项目
press-ui
比普通的组件只是多了条件编译,所以加一个支持条件编译的loader
就可以解决了,loader
代码地址在这里。
loader
使用方法如下:
- 安装 npm 包:
- 在
vue.config.js
中添加如下设置:
4. 共建
4.1. 后续规划
press-ui
后续规划包括:
- 支持
Android
、iOS
- 优化构建流程和开发体验
- 减小
npm
包大小 - 对外开源
4.2. 共建
欢迎体验、试用、共建,可以加入群聊,二维码过期可以私聊加入。
5. 技术细节
5.1. 项目结构
press-ui
的项目结构如下:
组件库除了组件外,还有文档、示例、工程化配置等部分。为了维护起来方便,我将示例、文档、组件都放在一个文件夹里,所以一个标准的组件文件夹目录如下:
src/packages
下就是由这些组件文件夹和一些公共文件构成。
上面的组织结构并不能直接用,还需要把README.md
移动到docs
中,把demo.vue
移动到src/pages
中。这里我写了脚本用来监听这些文件变动,发生变动后就把它们拷贝到需要的位置上,命令为npm run dispatch
。
5.2. 监听文件变化
监听用的是gulp
,这里有个比较重要的属性delay
,允许在执行任务之前等待许多更改,比如删除文件夹这种操作。delay
只支持这种方式:
不支持这样使用:
参考:https://www.gulpjs.com.cn/docs/api/watch/
5.3. 组件来源
press-ui
的组件并不都是从零开始写的,而是来源于vant
和项目自身沉淀的组件。
对于vant
组件转化,实现方式如下:
- 转化小程序版本的
vant
,即vant-weapp
- 将
wxml/wxss/js/json
转为vue
文件,即uni-app
编译的逆操作 - API 替换为
uni-app
的通用类型 - 条件编译处理 API 差异部分
这样做的好处是,可以大大提升组件编写效率,且 API 保持与vant
一致,从而方便用户由h5
项目平滑迁移到uni-app
项目。
对于项目中沉淀的组件,需与业务完全解耦后沉淀,并且需要具有一定的通用性或复杂度。为什么呢,这样可以让press-ui
更稳定,减少变化,发挥press-ui
的作用。
5.4. 组件质量
如何评价一个组件呢,可以从下面几个维度:
- 通用性,好的组件一定是通用的,即满足多种场景需求,表现上看就是有很多
props
、slot
,开发者想怎样用就怎样用 - 兼容性,可在低端机、横竖屏、大小屏等不同场景,都有良好的展示、交互效果
- 性能,可满足数据量大等场景
对于业务组件,通用性强的前提是,与业务充分解耦,如何做到呢?
- 不能存在业务状态码,多重判断逻辑应该前置完成
- 关注点分离,关注组件自身,而非业务
- 一个衡量标准是业务更新迭代,业务组件却一直稳定
- 能用函数调用的,就用函数调用,为什么呢?因为
js
比html
更灵活,灵活意味着通用型更强
5.5. BEM
笔者对项目中之前的组件,全部进行了BEM改造,以press-dialog
为例,改造前:
改造后:
可以看出,可读性大幅增强。
5.6. 新组件一键接入
新增组件只需要执行命令:
然后交互式的输入组件英文名、中文名等内容即可。
为了维护方便,内部会有一个component-config.json
文件,保存了所有的组件信息,包括名称、类型等。文档和示例的路由配置都是从这个文件生成。
这样的好处是要删除一个组件时,只要改变这个配置文件,然后执行npm run gen:config
即可,同理,对于组件名称变动、类型变动也是一样的。
这个配置文件相当于一个收口,可以很方便的管理文档和示例。
可以看出,这个配置主要驱动了:
- 文档的
sidebar
- 示例的首页列表
- 示例的
pages.json
- 示例的
i18n
配置
5.7. 类名兼容
press-ui
的类名前缀统一为press-
,而vant
的类名前缀为van-
,对于老项目,press-ui
提供了一种兼容方案,允许不改动之前的样式文件。
使用方式为,给组件添加一个属性:extra-class-prefix="van-"
。
5.8. API平滑升级方案
组件API,可分为props
和event
。event
的话直接多emit
新的就好了,props
的话需要先判断新旧prop
的值是否为默认值。
如果哪一个不等则使用那一个,新
prop
优先级大于旧prop
。如果都相等,就用新prop
的值。
注意,这里的相等不能是简单的===
,需要考虑引用类型。
此外,还要考虑取子属性的场景,比如this.a.b.c
。
5.9. children循环引用
循环引用的对象不要放在data/computed
中,直接在created
中声明,比如press-tabs
中的children
。
5.10. 跨组件通信
vant-weapp
用的是reletion
,press-ui
用的是provide/inject
,也可以用eventBus
。