一个月搭建组件数量50+的多端组件库

523 阅读4分钟

未命名文件.png

摘要

小电多端组件库—vantui,开源一年了~.分享下我们是如何在一个多月的时间里搭建组件数量50+的多端组件库,同时诚挚邀请对多端有诉求的团队进行试用和交流,希望有更多的小伙伴参与到vantui组件库的建设中🔥

背景

  1. 为什么要做多端组件库?

一年之前,小电创新事业部前端团队在业务开发迭代过程中,先后上线了基于Taro的微信小程序、字节小程序、快手小程序以及h5应用,由于当时taro&react组件库资源较少,仅有的TaroUI在样式交互的兼容性也不是那么的友好,于是我们决定做自己的多端组件库。

  1. 为什么要反编译小程序来开发多端组件库?

当时前端组内人员不足,从零搭建组件库需要漫长的时间。我们想要比较快的去复用其它组件库的设计,而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的兼容性没有那么理想如createIntersectionObserverCanvas等需要自己hack。
  • 针对hooks依赖过多问题,一般我们通过vscode eslint工具检查和补全依赖,依赖超过4个左右的时候尽可能做逻辑拆拆分多个静态函数和hooks函数。依赖多且难以拆分的普通函数,我们选择不用hooks包裹,此外useEffect等副作用的依赖需要通过代码调试去确定正确的依赖。

特性

  • 基于 Taro 开发的 UI 组件,支持React生态
  • 使用 TypeScript 编写,提供完整的类型定义
  • 支持 Taro(H5、微信小程序、支付宝小程序、...)
  • vant-weapp 的 UI 和 API 尽可能的保持一致,同时持续跟进其 commit 纪录
  • 50+ 个高质量组件,覆盖移动端主流场景
  • 支持按需加载
  • 主题定制

架构设计

未命名文件 (1).png

  • 构建:组件构建,参考vant-cli, 遍历源文件使用babel依次编译,输出eslib两个文件,分别对应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 发展做出的贡献: contributors

最后欢迎大家star🙏, 以及进群交流

WX20221206-174225@2x.png

微信群满 200 人,需手动拉群。添加好友请备注“AntmJS”,我们会尽快拉你进群交流

WX20221206-171150@2x (1).png