Skip to content

关于组件库

前言

hi ~大家好

我是田同学,我是开源组件库 tyh-ui 的作者,在这篇文章中,来讲一下我从做开源到现在,已经接下来的打算,做一些总结。

为什么会做开源组件库

在去年中旬的时候,我偶然之间看到了一个视频,讲的就是手写 element-ui 的一些组件。在这之前,虽然 vue2 我已经用了很久了,各种的组件库也用过不少,但是没有实际的去了解过组件库是如何实现的,当时还比较奇怪呢,为什么下载了 element-ui 之后,就可以使用特定的标签呢?比如 <el-button></el-button>

所以,我通过这个视频了解到了,原来组件库的内部,也都是一个一个的 *.vue 文件来组成的,通过插槽、传值的方式来渲染出不同的样式和内容。

开始也自己实现了几个简陋的组件进行测试,效果还是不错的,比如最简单的按钮组件,为什么通过传递不同的 type,就可以按钮的样式进行切换?具体按钮组件的实现原理,我在 b 站上做过按钮组件实现原理可以参考一下。

之后又尝试做了一些简单的组件,后来在测试的时候,感觉自己做的还不错,还是比较满意的,所以就在 2021年5月份的时候创建了仓库,发布了这个项目,做了 tyh-ui 组件库,就一直维护到了今天。

为什么是 tyh-ui2

如今的 tyh-ui,的安装命令是:

shell
npm i tyh-ui2

那么为什么安装的是 tyh-ui2 呢?

因为我在刚开始做组件库的时候,使用的是 vue2 进行开发的,当时的仓库是 tyh-ui-old,仓库是后改名才为 tyh-ui-old,之前叫 tyh-ui,所以当时在 npm 上发布之后,安装的命令就默认成为了:

shell
npm i tyh-ui

npm 的仓库在这里

因为当时的所有组件都是使用 Option API 来写的,记得当时写到了面包屑组件的时候,我就开始接触 vue3 了。vue3 最新的 Composition APIscript setup 语法糖,不禁让我感到惊艳,这样的写法是在是太爽了,个何况当时在社区中包括一些朋友都已经在项目中用上了 vue3,所以我就打算将自己的组件库也升级成兼容 vue3 的版本。升级起来还是比较容易的,当时就又新建了一个仓库,来上传新一代的 tyh-ui,所以仓库取名为 tyh-ui2,所以在 npm 发布出去的时候,名字也就叫 tyh-ui2 了。

后来两个组件库我同时维护,开发出来一个新组件,直接写两份代码,一个是 Option API,一个是 Composition API,两个组件库同时维护。

又过了一段时间之后,vue3 已经成为了默认版本,我感觉到了再继续维护 vue2 的组件库也没有什么意义了,还不如直接将一个做好,有些两套代码的时间,我不如将一份代码优化好。

所以,我就将之前 vue2 版本的组件库仓库名从 tyh-ui 改为了 tyh-ui-old,仓库也直接归档了,官网也给出了不再维护的提示信息。然后又将 tyh-ui2 的仓库名,改为了 tyh-ui

这也就是说虽然仓库名叫 tyh-ui,可实际是 tyh-ui2,在后文的叙述中,我也使用 tyh-ui 来代表 tyh-ui2

迭代优化

今天的仓库,已经有了 427 次的提交记录,其中有 18 条是合并的 PR,也就是说自己提交了 409 次。

经历这么多次的提交,仓库从开始,到中间,再到现在,发生了惊天腹地的变化,下面介绍一次比较重大的优化部分。

  • 开始

开始的时候基本上都是只是为了实现效果即可,所以内部代码有些可能需要一个计算属性就可以解决的问题,会写出多个计算属性。

有较多的冗余代码可以进行优化的地方,并且没有严格的类型校验。

  • 代码和样式优化

第一次重大的优化是将每个组件内部的函数都进行了封装处理,保证了暴露在外面的函数或者变量都是有用的,并且加入了类型校验。

组件的样式也使用了统一颜色主题,部分组件进行重写样式,每个组件的样式表至少优化掉几十行的样式。实现代码减少,效果更好。

  • 格式和提交规范制定

后面加入 eslint 代码格式校验,以及提交规范等,在 commit 的时候进行对所有文件的格式化,让所有组件的格式都是符合标准的,并且提交的时候必须加入提交信息。

关于规范可以见这里

  • TypeScript 支持

后面就开始学习了 TypeScript,了解了 ts 的强大之处,并边学边再一次重写组件库,组件的 props 进行了严格的类型校验。

每个组件标记 lang="ts",并且所有组件的 props 都单独抽离出来了一个单独的 prop.ts 文件,每一个参数都有严格的类型校验,可选参数使用 PropType 进行双重类型校验,type 也单独抽离出来了一个 type.ts 文件。

  • monorepo + pnpm 构建

后来有发现社区中很多的项目的目录结构和我的目录结构有着很大的差异,因为我的就直接是一个通过 npm init vite xxx 来创建出来的 vue3 的项目,而其他组件库的项目的结果并不是这样的,就开始研究他们的项目结构,后来得知这种项目结构较 monorepo

了解了之后,就开始各种查资料查文章进行学习研究,大概研究了一天+半个晚上,终于在 2021年03月17日晚上11点 自己搭建出来了 demo 的雏形。之后第二天又去找了大佬帮忙指点了一下,又改了一写部分之后才正式的完成了 monorepo + pnpm 的项目。

很快,我就将 tyh-ui 的仓库进行了又一次重大的改版,将项目重头到尾的 23 个文件全部进行了更新。

在 3 月 18 日这天,我想改变一下官网文档的编写方式,因为发现了一个可以将 markdown 转换为 vue 组件的库,叫 vite-plugin-md,就像使用它来进行重写文档,目前还正在编写中。

tyh-ui 的优势

有一说一,tyh-ui 在我看来还是一个很有优势的组件库,主要有以下几个原因:

  1. 足够轻量级

性能优化,这个词可谓是现在对于前端工程师必备的一个技能,对于性能优化,我首先想到的就是:在不影响正常使用的情况下,尽可能的减小包的体积。在这一点上,tyh-ui 可谓是占了比较大的优势,可以通过 npm tyh-ui 来看到它的体积,只有 189kb,而且内部包含了 30+ 常用组件。

为做到这一点,我做了很多的细节的优化,比如说,绑定的 class,可以参考下面代码段:

html
<button class="tyh-button" :class="[`tyh-button-${type}`]">
  <slot />
</button>

上面代码中是一个静态的 class,和一个动态的 class,那么我进行优化之后,就会变成:

html
<button :class="[`tyh-button-${type}`, 'tyh-button']">
  <slot />
</button>

这样无形中就会优化出来了一些字符,我的要求就是:能优化的地方必须要优化,但是也要保证代码的健壮。

  1. 更适合新手阅读源码

在很多新手在读组件的源码的时候,直接读那种大型的组件库,如 element-plus、naive-ui 等,它们的源码读起来可能会十分的痛苦,有几个原因:

  • 你对源码可能并不熟悉
  • 你可能并不了解 jsx
  • jsx 阅读起来本来就不是很友好

现在社区中大多数组件库都是使用 jsx 来写的,所以并不适合去通过阅读源码来了解组件的内部实现原理。因为我的组件库是使用 template 来编写的,所以比较适合于阅读源码,这也是我要说的下一个优势。

  1. 使用 template 编写

关于使用 template,和 jsx 的区别,可以通过为什么 Vue3 的组件库都在使用 jsx/tsx? 这片文章来进行了解到答案。

所以,tyh-ui 会一直保持使用 template 来编写的,目前还没有使用到 jsx,但是不排除会有一些极其动态的组件产生,比如下面场景,不得不说 jsx 的优势:

通过传递参数,参数为 1、2、3、4、5、6 其中的一个,通过传递的数字不同,渲染不同的 h几 标签,如果使用 template 来写,可能就会成为下面这样:

html
<template>
  <h1 v-if="num === 1">hello</h1>
  <h2 v-if="num === 2">hello</h2>
  <h3 v-if="num === 3">hello</h3>
  <h4 v-if="num === 4">hello</h4>
  <h5 v-if="num === 5">hello</h5>
  <h6 v-if="num === 6">hello</h6>
</template>

<script lang="ts" setup>
  defineProps({
    num: Number
  })
</script>

这样的代码,不免是有些不友好的。关于 jsx,在这里不过多赘述。

所以,希望你可以通过 tyh-ui,了解到组件的开发思想和设计模式,在不久的将来,带着这些思想,孕育出更高阶的组件库。

准备开发新的组件库

最近我在开始研究,打算再一次开发一个全新的组件库,对于 tyh-ui,它其实还并没有被社区大多数人认可,每周的 npm 下载量最近可以保持在 400 ~ 600 左右,可这也并不是一个我想要的结果,我也希望自己的组件库也可以受到更多人的关注,所以我又一次开发了全新的组件库 fighting-design

新的小伙伴加入

欢迎你加入!

在这里,不需要你的技术有多么优秀,只希望你对做开源有足够的热爱。如果你有技术,你可以参加主要的开发;如果你是一个新手,可以来写 Ui 设计方面的开发,就算你技术水平一团糟,还可以看看文档,找一找错别字,提一提 issues 或 pr 呢,不是吗?