2021-03-06-【UI组件库】10分钟搞定自定义vue组件库

10分钟搞定自定义vue组件库:kissing_cat:

前言:sunny:

随着项目的日趋壮大,有时候原有的组件不能满足我们的各种需求,就需要在原有的组件上进行改造。自定义的个性化UI组件越来越多,为了更好地管理它们,同时提高组件的可复用性、扩展性,决定打造一套完整的UI组件库。

技术栈:sunny:

  • vue-cli3
  • vue2.X的基本语法
  • npm的发布

完整项目目录结构:sunny:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
wwlocal-ui
├─ .eslintrc.js
├─ .gitignore
├─ .npmignore
├─ babel.config.js
├─ docs // vuepress开发目录
│ ├─ .vuepress
│ │ ├─ components // 在markdown中可以使用的vue组件
│ │ │ ├─ ww-search-bar.vue
│ │ ├─ config.js // vurepess配置修改入口,包括左边sidebar,右上方nav导航菜单等
│ ├─ README.md
│ └─ views
│ ├─ basic-components
│ │ ├─ searchBar.md
│ └─ business-components
│ ├─ xxx.md
├─ package-lock.json
├─ package.json // 与npm发布相关,记录版本号,包入口文件地址
├─ packages // 组件库源码目录
│ ├─ search
│ │ ├─ index.js
│ │ └─ src
│ │ └─ search.vue
│ ├─ index.js // 组件库源码组件入口文件,执行npm run build的目标文件
├─ public //公共资源入口,如favicon
│ ├─ favicon.ico
│ └─ index.html
├─ static //静态资源入口,如icon图标
│ ├─ image
├─ README.md
├─ demo
│ └─ page
│ │ └─ testSearchBar.vue
│ ├─ App.vue
│ ├─ main.js
├─ vue.config.js

创建项目:sunny:

项目名起自己觉得有意义的名字就行了

$ vue create demo-ui

注意:由于我们是开发一个第三方依赖库,我们选择 Manually select features

选择那些特性需要安装在项目中

1
2
3
4
5
6
7
8
9
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
( ) Router
( ) Vuex
(*) CSS Pre-processors
(*) Linter / Formatter
( ) Unit Testing
( ) E2E Testing

系统默认的包含了基本的 Babel + ESLint 设置的 preset,我们只需要选择CSS配置。移动键盘上下键选择需要的特性,按下键盘空格键即可选中

安装哪一种 CSS 预处理语言

1
2
3
4
Sass/SCSS (with dart-sass)
Sass/SCSS (with node-sass)
Less
Stylus

由于政务微信中的样式采用Sass,所以我们选择第一项即可 为什么不选择第二项呢? 因为dart-sassnode-sass更好下载

选择代码风格

1
2
3
4
ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
ESLint + Prettier

一般选 ESLint + Prettier的组合

那种方式进行代码格式检测

1
2
(*) Lint on save
( ) Lint and fix on commit

选择Ctrl+S保存时检测代码格式即可

配置文件生成方式

1
2
In dedicated config files
In package.json

看个人喜好,我选第一种

是否保存预配置

1
Save this as a preset for future projects? (y/N)

看项目需要,我这里选择 N。回车后,系统会自动帮我们把选择的配置集成到模板中,然后生成一个完整的项目。

调整目录:sunny:

将src目录改为demo,用于测试我们自己开发的UI组件(在引入vuepress之后这个文件夹也不再需要了)。在根目录中创建一个packages目录用来存放我们要开发的UI组件;

新增packages目录,该目录未加入webpack编译;

注:cli3 提供一个可选的 vue.config.js 配置文件。如果这个文件存在则他会被自动加载,所有的对项目和webpack的配置,都在这个文件中。

注: vue的package文件夹采用了monorepo:monorepo是一种将多个package放在一个repo中的代码管理模式,摒弃了传统的多个package多个repo的模式。关于monorepo可以在 Vue3.0 中的 monorepo 管理模式这篇文章中了解

webpack配置修改:sunny:

packages 是我们新增的一个目录,默认是不被 webpack 处理的,所以需要添加配置对该目录的支持。

chainWebpack 是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。在根目录创建vue.config.js文件,作如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 修改 src 为 demo
const path = require("path");
module.exports = {
pages: {
index: {
entry: "demo/main.js",
template: "public/index.html",
filename: "index.html"
}
},
// 扩展 webpack 配置,使 packages 加入编译
chainWebpack: config => {
config.module
.rule("js")
.include.add(path.resolve(__dirname, "packages"))
.end()
.use("babel")
.loader("babel-loader")
.tap(options => {
return options;
});
}
};

组件编写:sunny:

SearchBar 组件

  1. packages 目录下,所有的单个组件都以文件夹的形式存储,所有这里创建一个目录 search
  2. search 目录下创建 src 目录存储组件源码
  3. search 目录下创建 index.js 文件对外提供对组件的引用。
1
2
3
4
5
6
7
8
import SearchBar from './src/index.vue';
import { COMPONENT_PREFIX } from '../constants'

// 为组件提供 install 安装方法,供按需引入
SearchBar.install = function(Vue) {
Vue.component(COMPONENT_PREFIX + SearchBar.name, SearchBar);
};
export default SearchBar;
  1. /packages/search/src/index.vue核心组件代码。

导出所有组件:sunny:

  • 整合所有的组件,对外导出,即一个完整的组件库 修改 /packages/index.js 文件,对整个组件库进行导出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import Package from '../package.json';
import SearchBar from './search';
import { COMPONENT_PREFIX } from './constants'

// 存储组件列表
const components = { SearchBar };
const component_version = Package.version

// 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
const install = function(Vue) {
// 遍历注册全局组件
Object.keys(components).forEach(function(key) {
const item = components[key]
if (item.install) {
Vue.use(item);
} else if (item.name) {
// 统一加 组件前缀
const name = COMPONENT_PREFIX + item.name
console.log(name)
Vue.component(name, item);
}
});
};
// 判断是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export default {
// 导出的对象必须具有 install,才能被 Vue.use() 方法安装
version: component_version,
install,
...components
};

组件库打包

  • package.json 中的script下新增一条编译为库的命令,然后就可以使用npm run lib命令进行打包啦
1
2
3
"scripts": {
"lib": "vue-cli-service build --target lib --name zyx-ui --dest lib packages/index.js"
},

注:

  1. --target: 构建目标,默认为应用模式。这里修改为 lib 启用库模式。
  2. dest : 输出目录,默认 dist。这里我们改成 lib
  3. [entry]: 最后一个参数为入口文件,默认为 src/App.vue。这里我们指定编译 packages/ 组件库目录
  • 执行编译库命令
1
npm run lib

npm发布包

  • 首先创建一个npm账户 $ npm adduser 注册一个内部用户,具体操作同npm,可以自行百度。
  • 配置 package.json 文件中发布到 npm 的字段
  1. name: 包名,该名字是唯一的。可在 npm 官网搜索名字,如果存在则需换个名字。
  2. version: 版本号,每次发布至 npm 需要修改版本号,不能和历史版本号相同。
  3. description: 项目描述。
  4. main: 入口文件,该字段需指向我们最终编译后的包文件。
  5. keyword:关键字,以空格分离希望用户最终搜索的词。
  6. author:作者
  7. private:是否私有,需要修改为 false 才能发布到 npm
  8. license: 开源协议
  9. browserslist: 指定了项目的目标浏览器的范围
  10. repository: 指定代码所在的位置
  • 执行发布指令
1
npm publish
  • 另外,可在24小时内对已发布的包进行撤回操作 npm unpublish 你的包名

如果失败可加上 --force参数


2021-03-06-【UI组件库】10分钟搞定自定义vue组件库
https://zhangyingxuan.github.io/2021-03-06-【UI组件库】10分钟搞定自定义vue组件库/
作者
blowsysun
许可协议