我们在系统地学习如何开发前端的SPA项目时,在搭建完脚手架之后,不得不绕开的一个框架那就是UI库。UI库是一套集成的前端页面UI组件,可以帮助开发者更好地搭建美观的网站,缩短开发周期。我最近花了很长时间整理了Element-ui库的源码架构细节,下面通过这篇长文分段分享给大家
系统架构
我们首先从README.md这个markdown文档中:
README.md
可以得出:element-ui的最终形式就是一个外部的新Vue组件,可以添加集成到Vue主组件中,element-ui这个组件内部也包含着很多的Vue组件,例如Select、Button等等。
-
主入口文件:./src/index.js,此入口文件继承了所有element-ui的组件,并为原型提供了一部分创建组件的捷径方法,也是webpack打包的入口文件。
-
外部方法:./src/utils/…,此文件夹包含了element-ui库的大部分外部方法,用于优化,便捷一些核心组件内部的业务逻辑。
-
额外的外部方法:./src/mixins/…,此文件夹包含了element-ui库的一些外部方法。
-
交互操作方法:./src/directives/…,此文件夹包含了交互操作所规定的一些方法。
-
核心业务组件:./packages/…,此文件夹包含了element-ui所提供的API的核心代码实现,也是element-ui库的关键。
我们下面讲解element-ui库代码就从上面的五个大模块入手,简要地解析这个element-ui的源码是如何一步一步地实现整个ui库框架的。
主入口文件
此入口文件继承了所有element-ui的组件,并为原型提供了一部分创建组件的捷径方法,也是webpack打包的入口文件。
./src/index.js
主入口文件
我们可以看到主入口文件对packages核心组件的大量引入,我们可以把主入口文件看作是一个组件产品的集成体,为开发者的实际项目提供服务。下面就通过主入口文件来对packages的核心组件进行分析,然后通过packages核心组件中的外部方法,来寻找相应的方法,在进行分析。
核心业务组件
核心业务组件位于 /src/packages/ 文件夹中。是整个element-ui库的核心,提供了大量的组件服务给开发者。我们从使用ui库常见的一个组件el-button开始,来先初步地了解ui库内部的核心组件是如何工作的。
./packages/button/index.js
./packages/button/src/button.vue
button.vue
./packages/button/src/button-group.vue
button-group.vue
我们从el-button组件的入口文件index.js中可以发现,el-button用于展现button按钮的组件来源于src文件夹,使用了install方法,来使开发者开发实际项目中可以使用Vue.use()来进行全局注册。
我们再来看button.vue文件,这是一个很典型的vue单文件组件。规定了用用户该拥有的所有属性,以及内部的span字段,封装了click方法。
其中还有一个特别值得关注的点就是:在script中,使用了inject方法。在Vue框架中,包含这些组合关系,常见的例子有this.$parents为Vue实例访问其父实例。Vue提供了provide/inject,主要在开发高阶插件/组件库这一类复杂项目中使用,一般情况下,普通项目是不会用到的,这对选项(provide/inject)一起使用,使得祖先组件可以对其后代组件注入依赖。
-
provide:> Object | () => Object
-
inject: > Array | {[key:string]:string | Symbol | Object}
上面给出了所可能情况下的数据类型,provide返回的应该是一个对象或者一个对象返回的函数,该对象包含着组件注入后代组件的属性,无论层次有多深始终生效。
inject则是一个字符串数组或者一个对象,对象的key是本地的绑定名在可用的注入内容中搜索用的 key (字符串或 Symbol),或一个对象。我们的el-button例子中就继承了el-form和el-formitem的所有provide内容。