手把手教你快速制作基于Element UI组件npm包
本文主要介绍如何快速实现基于Element UI二次封装的组件发至npm,并在自己的项目中通过安装该npm包来调用该组件。
一、发布npm包
1、通过vue-cli初始化一个项目后,编写可复用子组件
这里我把可复用子组件放在了 src\components\common\组件名
目录中
项目中我开发了
DatePickerHasOps.vue
、 DatePickerLimit .vue
、DialogWithBtn.vue
、TablePage.vue
四个可复用子组件这里贴一下
DialogWithBtn.vue
的代码
<template>
<el-dialog :visible.sync="visibleDialog" v-bind="$attrs" v-on="$listeners">
<slot></slot>
<template #footer>
<slot name="footer">
<div class="dialog-footer-ct">
<el-button @click="cancelOp">取 消</el-button>
<el-button @click="sureOp" type="primary">确 定</el-button>
</div>
</slot>
</template>
</el-dialog>
</template>
<script>
export default {
name: 'dialog-with-btn',
props: {
visible: {
default: false,
type: Boolean,
},
},
computed: {
visibleDialog: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
},
},
},
methods: {
cancelOp() {
this.$emit('cancelEvent')
this.visibleDialog = false;
},
sureOp() {
this.$emit('sureEvent')
this.visibleDialog = false;
},
},
// data:{
// return {
// visibleDialog
// }
// }
}
</script>
<style scoped>
.dialog-footer-ct{
margin: 10px auto;
text-align: center;
}
</style>
2、在src\components\common\目录下新建一个index.js文件
index.js
import DatePickerHasOps from './DatePickerHasOps/DatePickerHasOps'
import DatePickerLimit from './DatePickerLimit/DatePickerLimit'
import DialogWithBtn from './DialogWithBtn/DialogWithBtn'
import TablePage from './TablePage/TablePage'
let plugins={};
const componentArray=[DatePickerHasOps,DatePickerLimit,DialogWithBtn,TablePage]
plugins.install=function (Vue) {
// 判断是否安装过
if(plugins.installed) return;
plugins.installed=true
// console.log('plugins.installed==========',plugins.installed)
// 获取地址栏特定搜索串内容
// Vue.prototype.$getSearchParam=function(name){
// const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
// const r = window.location.search.substr(1).match(reg);
// if (r != null) {
// return decodeURIComponent(r[2]);
// }
// return '';
// }
componentArray.forEach((item)=>{
Vue.component(item.name,item)
})
}
// /* 支持使用标签的方式引入 */
// if (typeof window !== 'undefined' && window.Vue) {
// install(window.Vue);
// }
// 也可参考 https://cn.vuejs.org/v2/cookbook/packaging-sfc-for-npm.html
export default plugins
3、编辑package.json文件
注意看里面的注释说明。
{
"name": "vue-ele-component-zonst", // 即将发布的npm包名
"version": "0.0.1",
"private": false, // 是否为私有 这里记得改为false
"description": "封装了zonst常用的组件库,如日期选择器、表格及弹窗等",
"license": "MIT",
"files": ["lib"], // 发布npm包后 使用者能够看到的你的文件夹或文件
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"lib": "vue-cli-service build --target lib --name vue-ele-component-zonst --dest lib/all src/components/common/index.js" // 为发布npm进行打包 里面的具体参数可参考 https://cli.vuejs.org/zh/guide/cli-service.html#vue-cli-service-build
},
"main": "lib/all/vue-ele-component-zonst.umd.min.js", // 这里为了 使用者在调用npm包时 可直接使用import xxxx from '你的npm包名'
"repository": {
"type": "git",
"url": "https://git.xxxxxx.com/xxxx-demo/vue-element-component.git"
},
"keywords": [
"vue",
"element-ui",
"dialog",
"datePicker",
"table"
],
"homepage": "https://github.com/",
"dependencies": {
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-service": "~4.4.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11",
"core-js": "^3.6.5",
"element-ui": "~2.3.9",
"vue": "^2.6.11",
"vue-router": "~3.3.4"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
4、运行 npm run lib 以便构建npm包文件
下图是构建生成的commonJS、umd及source map系列文件
image.png
5、本地测试构建后的效果
在main.js中
import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import router from './router'
import App from './App.vue'
// eslint-disable-next-line
import vueEleComponentZonst from '../lib/all/vue-ele-component-zonst.umd.min'
// import dialogWithBtn from '../lib/part/dialog-with-btn.umd.min'
// 实现免手动引入全局组件
// eslint-disable-next-line
//import globalImortComponents from '@/components/common/js/globalImportComponents'
Vue.config.productionTip = false
Vue.use(ElementUI).use(vueEleComponentZonst);
// Vue.use(ElementUI).use(dialogWithBtn);
// import '../node_modules/vue-ele-component-zonst/lib/all/vue-ele-component-zonst.css'
// import '../node_modules/vue-ele-component-zonst/lib/part/dialog-with-btn.css'
import '../lib/all/vue-ele-component-zonst.css'
// import '../lib/part/dialog-with-btn.css'
new Vue({
router,
// methods:{
//
// },
render: h => h(App),
}).$mount('#app')
调用DialogWithBtn 组件测试
<template>
<div>
<ol>
<li>在原有dialog基础上底部增加‘确定’和‘取消’按钮</li>
<li>支持dialog所有属性和事件</li>
</ol>
<el-button @click="editSome" type="primary">打开对话框</el-button>
<dialog-with-btn title="对话框标题" :close-on-click-modal="false" @cancelEvent="cancelCallback" @sureEvent="sureCallback" :visible.sync="visible">
这是一个对话框
</dialog-with-btn>
</div>
</template>
<script>
// const DialogWithBtn = () => import('@/components/common/DialogWithBtn');
export default {
name: 'test-dialog',
// components: {
// DialogWithBtn,
// },
data() {
return {
visible: false,
}
},
methods: {
editSome() {
this.visible = true
console.log('点击了编辑')
},
cancelCallback() {
console.log('点击了取消按钮')
},
sureCallback() {
console.log('点击了确定按钮')
},
},
}
</script>
<style scoped>
</style>
6、将npm的源改为npm官方的网址
以上测试无误后开始准备发布npm包
npm config set registry https://registry.npmjs.org
7、登录你注册好的npm帐号
npm login
输入npm帐号密码及邮箱
8、发布
npm publish
过一段时间后,会收到npm官方发的 npm发布成功的邮件
如果发布的是测试包,则可使用
npm publish --tag=beta
9、查看npm包
https://www.npmjs.com/package/vue-ele-component-zonst
二、使用npm包
1、安装vue-ele-component-zonst
npm i vue-ele-component-zonst
2、引入npm包
main.js
import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// import vueEleComponentZonst from 'vue-ele-component-zonst/lib/all/vue-ele-component-zonst.umd.min'
// import vueEleComponentZonst from 'vue-ele-component-zonst/lib/part/dialog-with-btn.umd.min'
import vueEleComponentZonst from 'vue-ele-component-zonst'
import App from './App.vue'
// console.log('vueEleComponentZonst',vueEleComponentZonst)
// console.log('ElementUI',ElementUI)
Vue.config.productionTip = false
Vue.use(ElementUI).use(vueEleComponentZonst);
// Vue.use(ElementUI);
// Vue.use(ElementUI).use(DialogWithBtn);
import 'vue-ele-component-zonst/lib/all/vue-ele-component-zonst.css'
new Vue({
render: h => h(App),
}).$mount('#app')
3、使用npm子组件
三、结语
以上为实现基于Element UI二次封装的组件发至npm最简单的方法,希望大家能够明白原理。在明白原理的基础后其实可以通过修改vue.config.js
来分别打包各个组件并通过不同路径或使用babel-plugin-import(或babel-plugin-component)插件来实现按需引入你想要的组件、控制打包后的文件类型等来减少项目的体积;
上述代码 我放在github 仓库中 vue-ele-component-zonst 及发布至npm官网了 https://www.npmjs.com/package/vue-ele-component-zonst
四、npm 私服搭建推荐
https://www.yukapril.com/2020/12/13/npm-server.html
1、Nenus
官网:https://www.sonatype.com/nexus/repository-oss
非常强大,各个公司基本上用的都是它!因为它可以同时处理 maven npm 等私有仓库。所以为了省事,很多公司就不会单独再部署其他私服了。
下载地址:https://www.sonatype.com/nexus/repository-oss/download
2、sinopia
已停止更新。 Github:https://github.com/rlidwka/sinopia
一样号称零配置的私服,整体和 Verdaccio 差不多
3、Verdaccio
官网:https://verdaccio.org
Verdaccio 是 Sinopia 开源框架的一个分支,持续更新,轻量级,操作少。
号称零配置的私服,直接用 node 启动就行,还提供 docker 版本。
体验下来,我觉得好处就是安装特别省事,无需太关注复杂的技术,也可以不用太配置,还带有个简洁的 UI 页面。
单纯是 npm 私服的话,我认为用它非常适合。而且体验和 npm 官网非常类似,支持的 npm 语法也非常好。
具体教程可见:快速搭建npm私服并发布npm步骤(无需数据库)
4、cnpm
依赖较多,相对笨重 ,操作多
五、自动更新版本号指令
npm version patch 更新修订版本
npm version minor 更新次要版本
npm version major 更新主版本
六、npm多人发包
npm owner add <user> [<@scope>/]<pkg>
详见:https://docs.npmjs.com/cli/v7/commands/npm-owner