在公司项目逐渐多起来的状况下,公共组件也多起来。不想每一次修改一下公共组件,都要去每一个项目中修改。这时候你就该学会用Vue CLI3 搭建组件库并用npm发布了,本文以基于element组件中Select 选择器和Tree 树形控件扩展出来的树结构数据下拉选择器的组件为例子讲解。css
npm uninstall vue-cli -g
卸载;npm install -g @vue/cli
安装Vue CLI3;vue --version
,查看Vue CLI的版本号是不是3.0以上,是表明安装成功。vue create fxft-tree-select
,fxft-tree-select
为项目名称;经过Vue CLI搭建的Vue组件库项目中有不少无用的文件和代码,须要对其作一次清洁。html
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
复制代码
改为 "scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build"
},
复制代码
由于在Vue CLI2中使用npm run dev
命令启动项目。npm install
安装依赖,安装成功后,执行npm run dev
,执行成功后在浏览器打开 http://localhost:8080/ ,页面展现以下图所示,说明Vue项目已经搭建成功。清洁后以下:vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
</head>
<body>
<div id="app"></div>
</body>
</html>
复制代码
清洁后以下:webpack
import Vue from 'vue'
import Router from 'vue-router';
Vue.use(Router)
function load(component) {
return resolve => require([`./views/${component}`], resolve);
}
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: load('home')
},
]
})
复制代码
清洁后以下:git
<template>
<div>
<router-view/>
</div>
</template>
复制代码
删除views文件夹中的About.vue和Home.vue文件,github
新建home.vue文件.内容以下:web
<template>
<div style="text-align:center">
<img alt="Vue logo" src="../assets/logo.png">
<p>欢迎使用Vue组件库项目</p>
</div>
</template>
复制代码
从新执行npm run dev,执行成功后在浏览器打开 http://localhost:8080/ ,页面展现以下图所示,说明Vue项目已经清洁成功。vue-router
清洁完毕后,但其仍是不知足咱们组件库项目开发的要求,须要咱们进一步配置。vue-cli
在Vue组件库项目中原来src文件夹的内容是demo展现的内容,因此文件名改为examples,比较形象。npm
在Vue CLI3中,项目的webpack配置是要在根目录下新建vue.config.js来配置。
在vue.config.js文件中配置内容以下:
module.exports = {
pages: {
index: {
entry: 'examples/main.js',
template: 'public/index.html',
filename: 'index.html',
},
},
}
复制代码
组件的代码在package文件夹中开发
const path = require('path');
function resolve(dir) {
return path.resolve(__dirname, dir)
}
module.exports = {
configureWebpack: {
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('packages'),
'assets': resolve('examples/assets'),
'views': resolve('examples/views'),
}
},
},
}
复制代码
关闭source map有两个好处
在vue.config.js文件中配置内容以下:
module.exports = {
productionSourceMap: false,
}
复制代码
是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码),
看成为一个库构建时,要将其设置为 false 省得用户本身导入 CSS。
在vue.config.js文件中配置内容以下:
module.exports = {
css: {
extract: false,
},
}
复制代码
在vue.config.js文件中配置内容以下:
module.exports = {
configureWebpack: {
output: {
libraryExport: 'default'
}
},
}
复制代码
固定端口
port: 8091,
开启热更新
hot: true,
固定打开浏览器
open: 'Google Chrome',
在vue.config.js文件中配置内容以下:
module.exports = {
devServer:{
port: 8091,
hot: true,
open: 'Google Chrome'
}
}
复制代码
咱们使用插件时候,通常会作两个步骤
import treeSelect from 'fxft-tree-select';
Vue.use(treeSelect);
复制代码
那你可知为何要这么使用。
Vue.use()
安装 Vue.js 插件。若是插件是一个对象,必须提供 install 方法。若是插件是一个函数,它会被做为 install 方法。install 方法调用时,会将 Vue 做为参数传入。
该方法须要在调用 new Vue() 以前被调用。
在今天写的树下拉选择器组件是一个对象,因此要提供install的方法,并暴露出来。
install方法
官网这么介绍:这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。
那么我在packages文件夹中新建index.js文件中写入:
import treeSelect from './src/index.vue';
treeSelect.install = function(Vue) {
Vue.component(treeSelect.name, treeSelect);
};
export default treeSelect;
复制代码
<template>
<el-select v-model="value">
<el-option value="1">1</el-option>
<el-option value="2">2</el-option>
</el-select>
</template>
<script src="./js/index.js"></script>
复制代码
export default {
name: 'treeSelect',
data(){
return {
value:'',
}
}
}
复制代码
npm install element-ui --save
import 'element-ui/lib/theme-chalk/index.css';
import { Select, Option, Tree } from 'element-ui';
import treeSelect from '@/index';
Vue.use(Select);
Vue.use(Option);
Vue.use(Tree);
Vue.use(treeSelect);
复制代码
<template>
<div style="text-align:center">
<img alt="Vue logo" src="../assets/logo.png">
<div>
<tree-select></tree-select>
</div>
</div>
</template>
复制代码
你们注意到
import treeSelect from '@/index';
Vue.use(treeSelect);
复制代码
在home.vue中<tree-select></tree-select>
这样使用。
咱们换成这样引入,也能够正常显示
import myTree from '@/index';
Vue.use(myTree);
复制代码
可是若是咱们换成<my-tree></my-tree>
这样使用,则会报组件未定义的错误。
为何呢。由于<tree-select></tree-select>
这样使用,是根据packages/src/js/index.js文件中的name:'treeSelect'
,而不是根据Vue.use(treeSelect)
,因此咱们在写组件文档时候,组件标签必定要在文档中体现处理。
组件调试环境搭建完了,开发过程就不详细介绍了。最后会把git仓库地址公布出来,下面介绍一下怎么用npm发布。
若是你们须要详细的开发过程介绍,能够给我留言,看状况写详细开发流程。
在package.json文件中写入:
"scripts": {
"dev": "vue-cli-service serve",
"lib": "vue-cli-service build --target lib --name tree-select --dest lib packages/index.js"
},
复制代码
--target
: 构建目标,默认为应用模式。这里修改成 lib 启用库模式;--name
: 打包后的文件名;--dest
:输出目录,默认 dist
。这里咱们改为 lib
;[entry]
:入口文件,默认为 src/App.vue。这里咱们指定编译 packages/index.js
。执行命令npm run lib
后,会发现项目中多了一个文件夹。
lib/tree-select.common.js:一个给打包器用的 CommonJS 包 (不幸的是,webpack 目前还并无支持 ES modules 输出格式的包)
lib/tree-select.umd.js:一个直接给浏览器或 AMD loader 使用的 UMD 包
lib/tree-select.umd.min.js:压缩后的 UMD 构建版本
在package.json文件中写入:
"main": "lib/tree-select.umd.min.js",
复制代码
在package.json文件中写入:
"private": false,
复制代码
在package.json文件中写入:
"keyword": "tree-select tree select",
"description": "基于element组件中Select 选择器和Tree 树形控件扩展出来的树结构数据下拉选择器",
"author": "pengyh",
复制代码
将package.json文件中"name": "fxft-tree-select"
的fxft-tree-select复制到npm官网上查重。
若是name
值有重复须要修改,不然发布不上去,会提示你是否有权限修改此库。
对照package.json文件中"version": "0.5.0",
,0.5.0
是否重复版本,若是重复,须要手动更新版本,不然会提示不能在之前发布的版本上发布
项目中只有编译后的 lib 目录、package.json、README.md才是须要被发布的。咱们须要在.npmignore文件中设置:
examples/
packages/
public/
vue.config.js
babel.config.js
复制代码
在README.md,要写清楚,怎么安装,怎么引入使用,有哪些参数,哪些方法,哪些事件等,这是很是关键的
首先须要到 npm 上注册一个帐号,注册过程略。
若是配置了淘宝镜像,先设置回npm镜像: 执行命令npm config set registry http://registry.npmjs.org
执行命令npm login
按步骤输入用户名、密码、邮箱,每一个步骤回车进入下一步
执行命令 npm publish
,若是成功以下图
打开淘宝 NPM 镜像,将组件名fxft-tree-select输入进行搜索 点击下图所示进行同步
npm install fxft-tree-select --save
import treeSelect from '@/index';
Vue.use(treeSelect);
复制代码
在项目这样<tree-select></tree-select>
这样使用。
以上只是讲解了,单个组件的组件库怎么开发。后续还有多个组件的组件库怎么开发,怎么按需引入及怎么搭建私有的npm库。
项目地址:fxft-tree-select