一:为什么需要组件库(组件化)
二:搭建简单组件库并发布npm
三:timeline组件
四:根据工作现状,需不需要组件库(讨论)
1、为什么需要组件库(背景)
- 在大型软件系统中,web应用的前后端已经实现了分离,而随着REST软件架构的发展,后端服务逐步倾向于微服务,简单来说就是将一个大型后端服务,拆分成多个小服务,它们分别部署,降低了开发的复杂性,而且提高了系统的可伸缩性。而前端方面,随着技术的发展,开发的复杂度也越来越高,传统开发模式总是存在着开发效率低,维护成本高等的弊端
- 传统开发方式效率低以及维护成本高的主要原因在于很多时候是将一个系统做成了整块应用,而且往往随着业务的增长或者变更,系统的复杂度会呈现指数级的增长,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身
- 针对此弊端,其实业界早就有了一些探索,我们希望一个大且复杂的场景能够被分解成几个小的部分,这些小的部分彼此之间互不干扰,可以单独开发,单独维护,而且他们之间可以随意的进行组合。就拿电脑主机来说,一台整机包括CPU,主板,内存,硬盘等等,而这些部件其实都是由不同的公司进行生产的,他们彼此之间根据一套标准分别生产,最后组装在一起。当某个部件出现问题时,不需要将整台主机都进行维修,只需要将坏的部件拿下来,维修之后再将其组合上就可以了。这种化繁为简的思想在后端开发中的体现是微服务,而在前端开发中的体现就是组件化。
- 随着Vue,React等以组件(指令等)为主的优秀前端框架的出现,前端组件化逐渐成为前端开发的迫切需求,当然这一迫切需求也逐渐成为一种主流,一种共识,它不仅提高了前端的开发效率,同时也降低了维护成本。开发者们不需要再面对一堆复杂且难阅读的代码,转而只需要关注以组件方式存在的代码片段。
2.搭建简单组件库并发布npm
步骤
我们通过官方的 vue-cli 初始化一个 Vue 项目,首先要安装vue-cli脚手架
npm install -g @vue/cli # or yarn global add @vue/cli
初始化项目
vue create greate-feature-ui
修改项目结构
- src修改为examples,这个里边就是可以供你进行测试组件,和编写官方文档的
- 根目录新增packages目录,存放所有的组件
- 根目录新增vue.config.js,目的是为了改造项目入口,改为:examples/main.js
module.exports = { pages: { index: { entry: "examples/main.js" // 更改项目入口 } } }
现在我们来做一个button组件的例子
- 在packages下新建button文件夹,button下新建index.vue,并在packages下新建index.js作为最终导出所有组件的总出口文件
- packages/button/src/button.vue文件内容可以先简单一些
<!-- button组件 --> <template> <button>aaaa</button> </template> <script> export default { name: "GfButton", data() { return {}; }, }; </script>
- packages/button/index.js对外提供引用,提供按需引入
import GfButton from './src/button'; // 为组件提供 install 安装方法,供按需引入 GfButton.install = function(Vue) { Vue.component(GfButton.name, ElButton); }; export default GfButton;
packages/index.js---为了导出所有组件,从而让别人在使用我们的UI库的时候.可以引入之后,通过Vue.use的方式引入.
/** * 导出所有组件的总出口文件 */ import Button from "./button/src/button.vue"; const components = [Button]; // 定义 install 方法,接手Vue作为参数传入 const install = function (Vue) { // 首先需要判断是否安装 if (install.installed) return; install.installed = true; // 遍历注册所有组件 components.map((component) => { if (typeof component === "undefined" || !component.name) return; Vue.component(component.name, component); }); // components.map(component => Vue.use(component)) // 检测是否是vue环境 if (typeof window !== "undefined" && window.Vue) { install(window.Vue); } }; export default { version: "1.0.0", // 导出的对象必须具有 install,才能被 Vue.use() 方法安装 install, ...components, };
发布到npm
我们需要在根目录package.json文件中添加一条命令用于编译为库,在库模式中,Vue是外置的,这意味着即使在代码中引入了 Vue,打包后的文件也是不包含Vue的。
"scripts": { // ... "lib": "vue-cli-service build --target lib --name greate-feature-ui --dest lib packages/index.js"
}
--target
: 构建目标,默认为应用模式。这里修改为lib
启用库模式。--dest
: 输出目录,默认dist
。这里我们改成lib
[entry]
: 最后一个参数为入口文件,默认为src/App.vue
。这里我们指定编译packages/
组件库目录。
执行命令npm run lib, 最终会在根目录生成lib文件夹,重点在于xxx.umd.min.js,这是我们最终打包后的文件
package.json其他配置如下
name
: 包名,该名字是唯一的。可在 npm 官网搜索名字,如果存在则需换个名字。version
: 版本号,每次发布至 npm 需要修改版本号,不能和历史版本号相同。(重要)description
: 描述。main
: 入口文件,该字段需指向我们最终编译后的包文件。(重要)keyword
:关键字,以空格分离希望用户最终搜索的词。author
:作者private
:是否私有,需要修改为 false 才能发布到 npm(重要)license
: 开源协议
最后就是发布npm了( 没有npm账号的需要先去注册账号),执行命令登录npm
npm login
登完后查看登录状态
npm whoami
执行发布命令
npm publish
3.timeline组件案例
组件封装的思想理念
如果我们把一个组件从编码到展示分为展示层,数据处理层和 API 层
那么,我们封装组件要做的其实就是将显示层和数据定义给处理好,固定的数据格式对应我们的组件模板
如果我们把一个组件放在 MVVM 模型中(其中这里 VM 视图模板我把它作为了我们父组件的一种抽象控制器 Control
那么,我们封装组件要做的就是视图和模板,由父组件的控制器来控制我们的组件展示
*封装过程中,仅暴露关键属性,提供多种可能,并且以比较常用的值作为“默认值”并明确定义,即可满足“大部分需求只需无脑引用,同时小部分的特殊需求也能被满足”
4.根据工作现状,需不需要组件库(讨论)
- 开发角度
- 公司角度