小小的前端有大大的夢想。作一個屬於咱們本身的 UI 組件庫應該是個不錯的小目標了。那。。。組件是什麼😯?我想應該不用多說,在平常開發中咱們每天與之打交道,你所寫的每個 vue 文件均可以當作是一個組件,只不過通用性有所區別而已。組件寫得多了,隨着時間的推移,你就會有寫一個組件庫的衝動了。其實更多的爲了提高 B 格😢,當和別人談論的時候,你說你寫過一個 UI 庫,別人就以爲你可能有點吊。好了,不吹 B,趕忙擼吧😜javascript
源碼地址:github.com/lgq627628/x…css
咱們可能習慣了在一個 vue 裏面引入組件的方式,因此先這裏要鞏固一下全局引入組件的方式。舉個栗子🌰,通常咱們的用法是這樣的:html
import Loading from '../components/loading'
// 方法一:name 是組件的名字
Vue.component(Loading.name, Loading)
// 方法二:前提是 Loading 有提供 install 這個方法
Vue.use(Loading);
複製代碼
上面兩種方式均可以用來全局註冊組件,可是參數不同,選擇哪一種方法均可以,但要留意一下第二種方法,這種方法須要組件自己有個 install 的方法。額。。。爲啥要有 install 的方法?這個你就當作是規定就好,你用人家的框架就得遵循人家的規則。扯犢子吧🐂,實際上是由於執行 Vue.use
的時候會執行裏面的 install 方法,因此咱們須要寫個 install。對此你不用較真,寄人籬下是這樣的,哦不對🙅♀️,應該是站在大神的肩膀上💪。前端
這步應該不用多說吧,執行一下 vue create xr-ui
(前提是你安裝了 vue-cli3),而後看本身喜愛選擇一些配置,幾下回車以後一個清爽的初始項目就有了。這裏我沒有選擇用 typescript(主要是我還沒習慣用它),因此選用 typescript 的同窗們注意啦,可能寫法會有少量不一樣,有勞大夥看着改下吧。vue
當咱們水平不夠的時候,模仿是一種強大的學習能力👏。java
小改了一下目錄以後,你會驚奇的發現項目運行不了了。不要緊,這很正常,畢竟 src 都不見了,路徑啥的確定得報錯。因此如今咱們來解決這個問題。 在根目錄下新建一個 vue.config.js 文件(新項目是沒有這個文件的),並寫入如下內容:node
const path = require('path')
module.exports = {
// 修改 pages 入口
pages: {
index: {
entry: 'examples/main.js', // 入口
template: 'public/index.html', // 模板
filename: 'index.html' // 輸出文件
}
},
// 擴展 webpack 配置
chainWebpack: config => {
// @ 默認指向 src 目錄,這裏要改爲 examples
// 另外也能夠新增一個 ~ 指向 packages
config.resolve.alias
.set('@', path.resolve('examples'))
.set('~', path.resolve('packages'))
// 把 packages 和 examples 加入編譯,由於新增的文件默認是不被 webpack 處理的
config.module
.rule('js')
.include.add(/packages/).end()
.include.add(/examples/).end()
.use('babel')
.loader('babel-loader')
.tap(options => {
// 修改它的選項...
return options
})
}
}
複製代碼
上面的註釋應該都寫的挺明瞭,主要就是修改別名、修改入口文件以及把新文件加入 webpack 編譯這幾個步驟。而後咱們再運行一下程序就能夠跑得通了。至於爲何這麼配置、或者怎麼配置,不瞭解的同窗能夠去 Vue Cli 官網看下,上面寫的是清清楚楚、明明白白,然而我也只是懂那麼一兩個配置而已😭😭😭,還沒學會 webpack 的套路,由於經常是用的時候看一眼,一陣子不用就又忘了,沒辦法🤷♀️腦子不行。webpack
一個組件庫沒有組件怎麼行呢,因此咱們要先寫個 test 組件(你能夠隨便寫,這不重要)。ok👌,咱們先在 packages 目錄下新建一個 test 文件夾,再在 test 文件夾下下面新建一個 src 文件夾,在 src 文件夾下面新建一個 test.vue 組件,大概長下面這樣子👇: git
<!--test.vue-->
<template>
<div class="xr-test" @click="handleClick">{{ num }}</div>
</template>
<script> export default { name: 'XrTest', // 這個名字很重要,它就是將來的標籤名<xr-test></xr-test>,坑了我一下 data () { return { num: 0 } }, methods: { handleClick () { this.num++ } } } </script>
<style lang="scss" scoped> .xr-test { width: 100px; height: 100px; line-height: 100px; border-radius: 50%; font-size: 30px; text-align: center; background: #24292e; color: white; } </style>
複製代碼
應該都能看懂吧,不過多解釋。⚠️這裏主要強調一點,就是 name 這個名字尤其重要,我就在這個坑裏呆了挺久。首先它是必需要寫的,爲啥呢,你能夠把它理解爲 id,具備惟一標識組件的做用,未來咱們但是要經過這個 name 來找到和斷定這是什麼組件,因此你寫的全部組件應該是不重名的;其次這個 name 就是咱們最終的標籤名,好比這裏咱們的 name 是 XrTest
,到時候咱們寫的標籤就長這樣 <xr-test></xr-test>
,就像 Element 同樣,name 是 ElButton
,用的時候就是 <el-button></el-button>
。github
讓咱們在 packages/test 下面新建一個 index.js 文件,具體代碼以下:
// 爲組件提供 install 方法,供組件對外按需引入
import XrTest from './src/test'
XrTest.install = Vue => {
Vue.component(XrTest.name, XrTest)
}
export default XrTest
複製代碼
這步的精髓就在於給組件擴展一個 install 方法,至於爲何要擴展這個方法,文章開頭已經說到了,是由於 Vue.use()
的須要,use 會默認調用 install 方法安裝,僅此而已。接着咱們在 packages 下面也新建一個 index.js 文件,注意和上面那個 index.js 區別開,上面那個是針對單個組件安裝的,這個是針對全部組件全局安裝的,先看代碼:
import XrTest from './test'
// 全部組件列表
const components = [
XrTest
]
// 定義 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)
}
export default {
install,
// 全部組件,必須具備 install,才能使用 Vue.use()
...components
}
複製代碼
這步的主要做用就是統一導出全部組件及暴露 install 方法。以前的 index.js 只是安裝單個組件,而如今這個 index.js 是循環安裝全部組件,具體使用就看你是否是要按需引用了。這裏給個目錄結構方便你們觀看:
ok,組件寫完了,接下來咱們就在 examples 下面測試一下,看看能不能引用成功。 首先在 examples 下的 main.js 中引入剛剛寫好的包,就像下面這樣:
yarn serve
,看看效果,嗯,還湊合吧。
在 vue-cli3 中咱們經過如下命令能夠將一個單獨的入口打包成一個庫:
// target: 默認爲構建應用,改成 lib 便可啓用構建庫模式
// name: 輸出文件名
// dest: 輸出目錄,默認爲 dist,這裏咱們改成 lib
// entry: 入口文件路徑
vue-cli-service build --target lib --name lib [entry]
複製代碼
要注意的是在庫模式中,打包出來的庫中是不包含 Vue 的。 而後咱們修改一下 package.json 文件,就像下面這樣:
npm run lib
就能生成庫啦,看看左側的目錄是否是多了個 lib 文件夾,那個就是咱們要發佈的東西。
萬事俱備,只欠發佈。
{
"name": "xr-ui",
"version": "0.3.0",
"description": "基於 vue-cli3 的 UI 組件庫",
"main": "lib/xr-ui.umd.min.js", // 這是 lib 目錄下的其中一個
"keywords": "xr-ui",
"private": false,
"license": "MIT"
}
複製代碼
# 這是複製 .gitignore 裏面的
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
# 如下是新增的
# 要忽略目錄和指定文件
examples/
packages/
public/
vue.config.js
babel.config.js
*.map
*.html
複製代碼
最後執行 npm login
登入 npm 帳號,再執行 npm publish
發佈便可,就這麼簡單的兩步就能夠,過一會在 npm 上就能搜到了。固然前提是你有個 npm 帳號,沒有的話去註冊一個吧,很 easy 的,而後還要搜下你的 npm 包名是否有人用,有的話就換一個。
終於,歷盡千辛萬苦,咱們能夠引用本身寫的庫拉,想一想就牛叉。別激動,讓咱們試驗一下,用 vue create new
另起一個新項目,而後 npm i xr-ui -S
,能夠在 node_modules 裏面看到咱們的包大概長這樣:
import Vue from "vue"
import XrUI from 'xr-ui'
import 'xr-ui/lib/xr-ui.css'
Vue.use(XrUI)
複製代碼
這樣咱們就能在頁面中引入組件啦,哈哈哈哈,賊開心,喜上眉梢。。。
<xr-test></xr-test>
複製代碼
想一想若是你爲團隊維護一個組件庫,那是多麼牛叉的事情。固然,好記性不如爛鍵盤,看懂並不表明掌握,只有本身體驗過纔是真的難忘,😓額。。怎麼忽然抒情了起來。 最後仍是強調一點吧,水平不夠的時候,模仿是一種必備的技能,就像我。不過不要緊,這只是個過程,當你寫了幾年的代碼後,總會有一些本身的想法,而後也能慢慢沉澱出一些屬於本身的東西,咱們只是站在巨人的肩膀上前行,僅此而已,回見👋👋👋