為何要進行組件庫開發
如果你所在的公司對于頁面的樣式沒有什么要求,那么你只要隨便拿一個組件庫來用就行了,比如element、iView等等,不用再重復造輪子了;
如果你目前只有個人用一個組件,或者是只對個別組件有要求,那么只要在你的工程里面開發一個.vue單文件組件就可以了;如果你的團隊想要一個更加快速的開發方式,希望有一套一類應用的標準,并且對組件的樣式有較高的要求,那么你就需要開發一個組件庫了。
正確的學習方式
我覺得我寫完這篇文章以后,大家看完可能只是能按部就班地開發一個組件庫而已,而且具體的記憶和理解不是很深,所以我覺得正確的方式應該是站在巨人的肩膀上,比如去查看element組件庫的源碼,去了解他的文件組織方式,文檔是如何管理的,主題文件是如何管理的,以及一些復雜組件是如何實現的。接下來,我們就進入正題。
步驟
我們來理一下整個步驟:
- 創建項目
- 調整項目結構
- 編寫組件
- 使用vue-cli-service庫模式打包編譯
- 發布到npm
創建項目
# 創建目錄
mkdir frog-ui
# 切換目錄
cd frog-ui
# 初始化項目
vue create .
調整目錄
將項目的目錄調整到以下形式,該目錄方式像是成了業界不成名的規定,element和iview都是以這樣的方式組織的。我覺得挺好的,所以不做修改了。
其中:
|-- examples // 為原來的src目錄改名而來,用于測試編寫的組件
|-- packages // 用于組織我們的組件庫
目錄調整以后,我們需要修改相應的webpack配置,使原來的src目錄指向修改后的examples目錄,修改vue.config.js文件:
const path = require('path')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
// 將entry指向examples
pages: {
index: {
entry: 'examples/main.js',
template: 'public/index.html',
filename: 'index.html'
}
},
// 為packages目錄添加babel-loader處理
chainWebpack: config => {
config.module
.rule('js')
.include
.add(resolve('packages'))
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
return options
})
}
}
編寫組件
packages目錄下面的文件組織情況如下:
其中:
|-- datePicker // 新編寫的組件,以datepicker為例
|-- theme-default // 主題文件
主題文件較為特殊,他作為單獨的一個包進行發布引入,方便進行主題發布,后面再進行介紹。下面對datePicker進行介紹:
datePicker.vue
<template>
<div>這是一個datePicker組件</div>
</template>
<script>
export default {
name: 'datePicker'
}
</script>
datePicker/src/index.js
// 導入組件,組件必須聲明 name
import datePicker from './src/datePicker.vue'
// 為組件提供 install 安裝方法,供按需引入
datePicker.install = function (Vue) {
Vue.component(datePicker.name, datePicker)
}
// 默認導出組件
export default datePicker
</script>
批量注冊組件
// 導入日期選擇器組件
import datePicker from './datePicker'
// 存儲組件列表
const components = [
datePicker
]
// 定義 install 方法,接收 Vue 作為參數。如果使用 use 注冊插件,則所有的組件都將被注冊
const install = function (Vue) {
// 判斷是否安裝
if (install.installed) return
// 遍歷注冊全局組件
components.map(component => Vue.component(component.name, component))
}
// 判斷是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
// 導出的對象必須具有 install,才能被 Vue.use() 方法安裝
install,
// 以下是具體的組件列表
...components
}
本地測試組件
我們的組件以及編寫完成,第一步先在本地進行測試:
examples/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 導入組件庫
import datePicker from './../packages/index'
import './../packages/theme-default/src/test.scss'
// 注冊組件庫
Vue.use(datePicker)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
examples/views/home.vue
<template>
<div class="home">
<datePicker></datePicker>
</div>
</template>
<script>
export default {
name: 'home'
}
</script>
如何在瀏覽器中就可以看到我們的組件運行成功了,下一步就是要將我們的代碼打包成npm庫了,那么需要通過vue-cli3中vue-cli-service的庫模式進行打包。
庫模式打包
# package.json
"script": {
"build-lib": "vue-cli-service build --target lib --name frog-ui --dest lib packages/index.js && npm run build-theme",
}
庫模式的介紹:點擊這里
執行:
npm run build-lib
項目的根目錄新增了lib文件夾,內容如下
其中:
- lib/frog-ui.common.js:一個給打包器用的 CommonJS 包
- lib/frog-ui.umd.js:一個直接給瀏覽器或 AMD loader 使用的 UMD 包
- lib/frog-ui.umd.min.js:壓縮后的 UMD 構建版本
修改package.json
修改packages.json,目前我的項目的完整package.json如下:
{
"name": "frog-ui",
"version": "0.1.0",
"private": false,
"lisence": "MIT",
"main": "lib/frog-ui.umd.min.js",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build-lib": "vue-cli-service build --target lib --name frog-ui --dest lib packages/index.js && npm run build-theme",
"build-theme": "gulp build --gulpfile packages/theme-default/gulpfile.js && cp-cli packages/theme-default/lib lib/theme-default",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^2.6.5",
"vue": "^2.6.10",
"vue-router": "^3.0.3"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.7.0",
"@vue/cli-plugin-eslint": "^3.7.0",
"@vue/cli-service": "^3.7.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"cp-cli": "^2.0.0",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^6.1.0",
"gulp-cssmin": "^0.2.0",
"gulp-sass": "^4.0.2",
"markdown-it-anchor": "^5.0.2",
"markdown-it-container": "^2.0.0",
"markdown-it-decorate": "^1.2.2",
"markdown-it-task-checkbox": "^1.0.6",
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0",
"vue-markdown-loader": "^2.4.1",
"vue-template-compiler": "^2.5.21"
}
}
主要要修改的是:
{
"private": false, // 是否私有,必須指定為false才能發布到npm
"main": "lib/frog-ui.umd.min.js", // 編譯后包的入口文件
}
根目錄添加.npmignore文件
發布到npm下,只需要lib目錄、package.json 和readme.md文件,所以需要忽略掉其他的目錄
.npmignore
examples/
packages/
public/
vue.config.js
postcss.config.js
babel.config.js
*.map
發布npm
# 設置要發布的源,我發布的是通過verdaccio搭建的私庫
npm config set registry http://registry.npmjs.org
# 登錄
npm login
# 發布
npm publish
下圖可以看到,我們的包發布成功了,關于私庫的搭建可以查看我另外的文章。
總結
整個過程有一點點繁瑣,但是能學到一些意外的知識,希望大家能夠動手嘗試。能力有限,文章中有寫得不對的地方請大家見諒。如果對你有幫助的話,可以幫忙點個贊哦 ~