知识前置
我们可能习惯了在一个 vue 里面引入组件的方式,所以先这里要巩固一下全局引入组件的方式。举个栗子🌰,一般我们的用法是这样的:1
2
3
4
5import Loading from '../components/loading'
// 方法一:name 是组件的名字
Vue.component(Loading.name, Loading)
// 方法二:前提是 Loading 有提供 install 这个方法
Vue.use(Loading);
基于vue-cli3打造组件库
搭建目录
快速创建项目
vue-cli3
1
$ vue create projectName
修改目录结构
- 把
src
目录名字改成examples
,这是用于展示组件示例的. 在根目录下新建一个
packages
文件夹,这是用来放组件的.你可能会问为什么要建这样的目录结构,问得好,原因很简单,因为别人是这样做的,所以借鉴(模仿)喽。。。
当我们水平不够的时候,模仿是一种强大的学习能力👏。
添加配置文件
小改了一下目录之后,你会惊奇的发现项目不能运行了,没关系,这很正常,毕竟 src 都不见了,路径啥的肯定得报错。所以现在我们来解决这个问题。 在根目录下新建一个 vue.config.js
文件(新项目是没有这个文件的),并写入以下内容:
1 | const path = require('path') |
上面的注释应该都写的挺明了,主要就是修改别名
、修改入口文件
以及把新文件加入 webpack
编译这几个步骤。然后我们再运行一下程序就可以跑得通了。至于为什么这么配置、或者怎么配置,不了解的同学可以去 Vue Cli 官网看下,上面写的是清清楚楚、明明白白.
编写组件
一个组件库没有组件怎么行呢,所以我们要先写个 test
组件(你可以随便写,这不重要),ok👌。
我们先在 packages
目录下新建一个 test
文件夹,再在 test
文件夹下下面新建一个 src 文件夹,在 src 文件夹下面新建一个 test.vue
组件,大概长下面这样子👇:
1 | <!--test.vue--> |
⚠️这里主要强调一点,就是 name
这个名字尤为重要, 否则可能会遇到坑。
- 首先它是必须要写的,可以把它理解为 id,具有唯一标识组件的作用,将来我们可是要通过这个 name 来找到和判定这是什么组件,所以你写的所有组件应该是不重名的;
- 其次这个 name 就是我们最终的标签名,比如这里我们的 name 是
EchojoyTest
,到时候我们写的标签就长这样<echojoy-test></echojoy-test>
,就像 Element 一样,name 是ElButton
,用的时候就是<el-button></el-button>
。
暴露组件
让我们在 packages/test
下面新建一个 index.js
文件,具体代码如下:
1 | // 对外提供对组件的引用,注意组件必须声明 name |
这步的精髓就在于给组件扩展一个 install
方法,至于为什么要扩展这个方法,文章开头已经说到了,是因为 Vue.use()
的需要,use 会默认调用 install
方法安装,仅此而已。
接着我们在 packages
下面也新建一个 index.js
文件,注意和上面那个 index.js
区别开,上面那个是针对单个组件安装的,这个是针对所有组件全局安装的,先看代码:
1 | import EchojoyTest from './test' |
这步的主要作用就是统一导出所有组件及暴露 install
方法。之前的 index.js
只是安装单个组件,而现在这个 index.js
是循环安装所有组件,具体使用就看你是不是要按需引用了。这里给个目录结构方便大家观看:
因为这步挺重要的,所以建议好好停下来理解消化一下🤔。。。
当然你可能会问道,为什么这样建目录?还能什么原因,因为 Element
是这样(如下图),所以我们这样写,仅此而已。
组件测试
ok,组件写完了,接下来我们就在 examples
下面测试一下,看看能不能引用成功。 首先在 examples
下的 main.js
中引入刚刚写好的包,就像下面这样:1
2import EchojoyUI from './../packages'
Vue.use(EchojoyUI);
然后把 examples/components
下面的 HelloWorld
里面的内容删了,写入自己标签组件,就像下面这样:
好了,最后让我们运行一下项目 npm run serve
,看看效果,嗯,还凑合吧。
库模式打包
在 vue-cli3
中我们通过以下命令可以将一个单独的入口打包成一个库:
1 | // target: 默认为构建应用,改为 lib 即可启用构建库模式 |
要注意的是在库模式中,打包出来的库中是不包含 Vue 的。 然后我们修改一下 package.json
文件,就像下面这样:
接着执行 npm run lib
就能生成库啦,看看左侧的目录是不是多了个 lib 文件夹,那个就是我们要发布的东西。
补充下,lib 目录下面的 js 之所以有好几种,是因为有两种规范(common 和 umd)
、是否压缩(min)
和映射 (map)
的区别,暂且知道有这么回事就行,不用深究。
发布到npm
万事俱备,只欠发布。
- 完善一下
README.md
文档,这个随便写两句就好 - 修改一下
package.json
文件:
1 | { |
- 在根目录下新建一个
.npmignore
文件,内容和.gitignore
差不多:
1 | # 这是复制 .gitignore 里面的 |
最后执行 npm login
登入 npm 账号,再执行 npm publish
发布即可,就这么简单的两步就可以,过一会在 npm
上就能搜到了。当然前提是你有个 npm
账号,没有的话去注册一个吧,很 easy 的,然后还要搜下你的 npm
包名是否有人用,有的话就换一个。
小试牛刀
终于,历尽千辛万苦,我们可以引用自己写的库拉,想想就牛叉。别激动,让我们试验一下,用 vue create echojoy-ui-use
另起一个新项目,然后 npm i echojoy-ui -S
,可以在 node_modules
里面看到我们的包大概长这样:
然后在 main.js 引入:
1 | import EchojoyUI from "echojoy-ui"; |
这样我们就能在页面中引入组件啦,哈哈哈哈,贼开心,喜上眉梢。。。
1 | <echojoy-test></echojoy-test> |
! vue-cli3(vue-cli2)
1 | vue init webpack projectName |
启动项目
npm run dev
浏览器输入1
http://localhost:8080
编写组件
在src
的components
新建组件limit
:即文件夹EchoLimit
->文件index.vue
+ 文件index+css
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// index.vue
<template>
<div class="echo-limit-container" v-if="visible === false">
<div class="echo-limit-container-inner">
<span class="echo-limit-text">
{{limitTip}}
</span>
</div>
</div>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false
},
limitTip: {
type: String,
default: '没有权限!!'
},
},
name: "EchoLimit" // 这个名字很重要,它就是未来的标签名<echo-limit></echo-limit>
};
</script>
<style>
@import "./index"
</style>
⚠️这里主要强调一点,就是 name 这个名字尤为重要,你可以把它理解为 id,具有唯一标识组件的作用,将来我们可是要通过这个 name 来找到和判定这是什么组件,所以你写的所有组件应该是不重名的;其次这个 name 就是我们最终的标签名,比如这里我们的 name 是 EchoLimit,到时候我们写的标签就长这样 Element
一样,name 是 ElButton
,用的时候就是
暴露组件
- 注册单个组件
在 components
的 EchoLimit
下面新建一个 index.js
文件,具体代码如下:
// 为组件提供 install 方法,供组件对外按需引入1
2
3
4
5import EchoLimit from "./EchoLimit/index.vue";
EchoLimit.install = Vue => {
Vue.component(EchoLimit.name, EchoLimit);
};
export default EchoLimit;
这步的精髓就在于给组件扩展一个 install
方法,至于为什么要扩展这个方法,文章开头已经说到了,是因为 Vue.use()
的需要,use 会默认调用 install
方法安装。
- 注册全局组件
让我们在 components 下面新建一个 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// index.js
import EchoLimit from './EchoLimit'
// 所有组件列表
const components = [
EchoLimit
]
// 定义 install 方法,接收 Vue 作为参数
const install = function (Vue) {
// 判断是否安装,安装过就不继续往下执行
if (install.installed) return
install.installed = true
// 遍历注册所有组件
components.map(component => Vue.component(component.name, component))
// 下面这个写法也可以
// components.map(component => Vue.use(component))
}
// 检测到 Vue 才执行,毕竟我们是基于 Vue 的
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
console.log(components[0].name) // 控制台输出组件的name,方便引用组件
export default {
install,
// 所有组件,必须具有 install,才能使用 Vue.use()
...components
}
目录结构方便大家观看:
组件测试
ok,组件写完了,接下来我们就在 HelloWorld.vue
下面测试一下,看看能不能引用成功。 首先在 src下的 main.js
中引入刚刚写好的包,如下所示:
1 | import EchoUI from './components' |
在 HelloWorld.vue中引入组件EchoLimit.1
2
3
4
5
6<template>
<div>
<EchoLimit></EchoLimit>
<echo-limit></echo-limit>
</div>
</echo-limit>
运行项目npm run dev
,会发现成功了!!!
过程同上!!!!!!!!!
总结:大功告成✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️
参考链接: