本文主要介紹如何快速實現(xiàn)基于Element UI二次封裝的組件發(fā)至npm粪摘,并在自己的項目中通過安裝該npm包來調(diào)用該組件肌稻。
一梗顺、發(fā)布npm包
1掘殴、通過vue-cli初始化一個項目后蝠嘉,編寫可復(fù)用子組件
這里我把可復(fù)用子組件放在了 src\components\common\組件名
目錄中
項目中我開發(fā)了
DatePickerHasOps.vue
、 DatePickerLimit .vue
杯巨、DialogWithBtn.vue
蚤告、TablePage.vue
四個可復(fù)用子組件這里貼一下
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)
// 獲取地址欄特定搜索串內(nèi)容
// 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", // 即將發(fā)布的npm包名
"version": "0.0.1",
"private": false, // 是否為私有 這里記得改為false
"description": "封裝了zonst常用的組件庫,如日期選擇器获诈、表格及彈窗等",
"license": "MIT",
"files": ["lib"], // 發(fā)布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" // 為發(fā)布npm進行打包 里面的具體參數(shù)可參考 https://cli.vuejs.org/zh/guide/cli-service.html#vue-cli-service-build
},
"main": "lib/all/vue-ele-component-zonst.umd.min.js", // 這里為了 使用者在調(diào)用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 以便構(gòu)建npm包文件
下圖是構(gòu)建生成的commonJS舔涎、umd及source map系列文件
5、本地測試構(gòu)建后的效果
在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'
// 實現(xiàn)免手動引入全局組件
// 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')
調(diào)用DialogWithBtn 組件測試
<template>
<div>
<ol>
<li>在原有dialog基礎(chǔ)上底部增加‘確定’和‘取消’按鈕</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官方的網(wǎng)址
以上測試無誤后開始準備發(fā)布npm包
npm config set registry https://registry.npmjs.org
7亡嫌、登錄你注冊好的npm帳號
npm login
輸入npm帳號密碼及郵箱
8、發(fā)布
npm publish
過一段時間后掘而,會收到npm官方發(fā)的 npm發(fā)布成功的郵件
如果發(fā)布的是測試包挟冠,則可使用
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子組件
三控淡、結(jié)語
以上為實現(xiàn)基于Element UI二次封裝的組件發(fā)至npm最簡單的方法,希望大家能夠明白原理止潘。在明白原理的基礎(chǔ)后其實可以通過修改vue.config.js
來分別打包各個組件并通過不同路徑或使用babel-plugin-import(或babel-plugin-component)插件來實現(xiàn)按需引入你想要的組件掺炭、控制打包后的文件類型等來減少項目的體積;
上述代碼 我放在github 倉庫中 vue-ele-component-zonst 及發(fā)布至npm官網(wǎng)了 https://www.npmjs.com/package/vue-ele-component-zonst
四凭戴、npm 私服搭建推薦
https://www.yukapril.com/2020/12/13/npm-server.html
1涧狮、Nenus
官網(wǎng):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
官網(wǎng):https://verdaccio.org
Verdaccio 是 Sinopia 開源框架的一個分支,持續(xù)更新遭垛,輕量級尼桶,操作少。
號稱零配置的私服锯仪,直接用 node 啟動就行泵督,還提供 docker 版本。
體驗下來庶喜,我覺得好處就是安裝特別省事小腊,無需太關(guān)注復(fù)雜的技術(shù)救鲤,也可以不用太配置,還帶有個簡潔的 UI 頁面秩冈。
單純是 npm 私服的話本缠,我認為用它非常適合。而且體驗和 npm 官網(wǎng)非常類似入问,支持的 npm 語法也非常好丹锹。
具體教程可見:快速搭建npm私服并發(fā)布npm步驟(無需數(shù)據(jù)庫)
4、cnpm
依賴較多芬失,相對笨重 楣黍,操作多
五、自動更新版本號指令
npm version patch 更新修訂版本
npm version minor 更新次要版本
npm version major 更新主版本
六麸折、npm多人發(fā)包
npm owner add <user> [<@scope>/]<pkg>
詳見:https://docs.npmjs.com/cli/v7/commands/npm-owner