摘要
小电多端组件库—vantui,开源一年了~.分享下我们是如何在一个多月的时间里搭建组件数量50+的多端组件库,同时诚挚邀请对多端有诉求的团队进行试用和交流,希望有更多的小伙伴参与到vantui组件库的建设中🔥
背景
- 为什么要做多端组件库?
一年之前,小电创新事业部前端团队在业务开发迭代过程中,先后上线了基于Taro的微信小程序、字节小程序、快手小程序以及h5应用,由于当时taro&react组件库资源较少,仅有的TaroUI在样式交互的兼容性也不是那么的友好,于是我们决定做自己的多端组件库。
- 为什么要反编译小程序来开发多端组件库?
当时前端组内人员不足,从零搭建组件库需要漫长的时间。我们想要比较快的去复用其它组件库的设计,而taro自带小程序反编译工具taro convert恰恰能够很好的帮助我们实现,我们选到了业界好评度最高的小程序组件库vant-weapp, 基于对它的反编译、重构快速搭建我们的多端组件库。
@antmjs/vantui组件库
vant-weapp编译后的重构
通过taro convert可以转换小程序代码,以下是一个简单微信组件的编译前后对比。
wxml代码
<view class="demo-home-nav">
<view class="demo-home-nav__title">{{ group.groupName }}</view>
<view class="demo-home-nav__group">
<view
wx:for="{{ group.list }}"
wx:key="title"
class="demo-home-nav__block"
data-url="/pages{{ item.path }}/index"
bind:tap="onClick"
>
{{ item.title }}
<van-icon name="arrow" custom-class="demo-home-nav__icon" />
</view>
</view>
</view>
微信js代码
Component({
properties: {
group: Object,
},
methods: {
onClick(event) {
const { url } = event.target.dataset;
if (getCurrentPages().length > 9) {
wx.redirectTo({ url });
} else {
wx.navigateTo({ url });
}
},
},
});
总体转换后的代码
@withWeapp({
properties: {
group: Object
},
methods: {
onClick(event) {
const { url } = event.target.dataset
if (Taro.getCurrentPages().length > 9) {
Taro.redirectTo({ url })
} else {
Taro.navigateTo({ url })
}
}
}
})
class _C extends React.Component {
render() {
const { group } = this.data
return (
<View className="demo-home-nav">
<View className="demo-home-nav__title">{group.groupName}</View>
<View className="demo-home-nav__group">
{group.list.map((item, index) => {
return (
<View
key={item.title}
className="demo-home-nav__block"
data-url={'/pages' + item.path + '/index'}
onTap={this.onClick}
>
{item.title}
<VanIcon
name="arrow"
customClass="demo-home-nav__icon"
></VanIcon>
</View>
)
})}
</View>
</View>
)
}
}
可以看到编译后的组件以高阶组件的形式呈现,原因在于为了更快的编译小程序端api,在编译前就预先通过高阶函数withWeapp实现小程序端的大部分钩子函数、observer、setData、props传递等api.提升编译效率和容错率。由于高阶组件作为基础组件,多层嵌套会导致性能问题,编译后的代码需要重构。重构的过程中我们主要做了以下工作:
- jsx和css基本上可以完全copy,其它的逻辑实现如:state实现data、effect和taro钩子实现小程序钩子、部分taro的api的兼容性没有那么理想如
createIntersectionObserver、Canvas等需要自己hack。 - 针对
hooks依赖过多问题,一般我们通过vscode eslint工具检查和补全依赖,依赖超过4个左右的时候尽可能做逻辑拆拆分多个静态函数和hooks函数。依赖多且难以拆分的普通函数,我们选择不用hooks包裹,此外useEffect等副作用的依赖需要通过代码调试去确定正确的依赖。
特性
- 基于
Taro开发的 UI 组件,支持React生态 - 使用 TypeScript 编写,提供完整的类型定义
- 支持 Taro(H5、微信小程序、支付宝小程序、...)
- 与
vant-weapp的 UI 和 API 尽可能的保持一致,同时持续跟进其 commit 纪录 - 50+ 个高质量组件,覆盖移动端主流场景
- 支持按需加载
- 主题定制
架构设计
- 构建:组件构建,参考vant-cli, 遍历源文件使用babel依次编译,输出
es和lib两个文件,分别对应esm和cjs两种代码格式, 由于vantui-demo中用到的是组件构建后的结果,在此基础上我们添加了组件构建的watch模式,监控源码的改动,时时输出新的组件构建结果。 - 文档同步:将组件ts类型和注释、css变量同步到文档
- demo代码同步:文档代码同步到vantui项目,保证和demo运行代码保持一致
- 文档构建:支持菜单、logo、demo地址等配置,webpack打包md文件生成文档
放心使用
整个组件库是依赖开源项目 Vant Weapp 的代码经过全量编译而来,所有样式文件及代码结构都与其保持高度一致,只是生命周期经过改造使其支持 React,很大程度避免了重新造轮子带来的各种问题,同时保留了 vant-weapp 多年积累的经验。
写在最后
本组件库的开发得益于Taro团队所提供的生态和有赞团队vant-weapp组件库,感谢 Taro 团队以及有赞团队为社区所作出的贡献。
同时感谢以下小伙伴们为 @antmjs/vantui 发展做出的贡献:
最后欢迎大家star🙏, 以及进群交流
微信群满 200 人,需手动拉群。添加好友请备注“AntmJS”,我们会尽快拉你进群交流