更新:javascript
npm install vuepress@0.14.11 -g
幾天前官方發佈的vuepress 1.x版本:謝謝你們支持!css
即使是一個青銅,也要用王者的心去編碼!html
Github上關於Vue的UI庫,大大小小不可勝數,即使是已經被推廣使用的成熟庫,也有不少。不少時候,咱們自研一套UI庫,不是想要作得多牛逼,競爭過別人(事實咱也幹不過人家,除非你不是一我的在戰鬥。畢竟這不只是個技術活,仍是個體力活),咱們僅僅是源自一個青銅對王者的仰望或者是爲知足心裏的需求。vue
這裏跟你們講一個一步一步自研UI庫的故事。java
原文地址:github.com/qiud...node
項目地址:Ange UIwebpack
開發一套UI庫,作成不難(這裏指的是半半半成品,全品也好難。。。),作好很難。但不慌,咱有祕籍:css3
Vue.js
和CSS3
仍是有必定的技術要求。那我要多牛逼才能寫好這個UI庫啊?這取決於你這套UI庫的實現高度。一套成熟的開源UI庫通常都具有如下幾個特色:git
所以,它們的目錄架構也出現了主要的兩種形式: github
& 有點大同小異,這裏咱們按照第一種架構去開發。觀察社區幾大UI庫發現,它們都是基於webpack
搭建了本身的構建配置,包括本地開發、生產環境構建、UI庫的打包等,創建一套本身的構建生態。咱們就不一樣了,業餘一點(實際上是善於應用開源工具),咱們的docs文檔是基於vuepress的,vuepress有本身一套的構建體系,因此咱們只須要針對UI組件源碼寫一份打包配置就行了。
下面開始搭建打包配置(其實就是好久之前咱們作的基於webpack的構建,如今cli用得多了,配置也不會寫了,碼耶): 首先在根目錄創建config
和build
文件夾,而後往兩個目錄分別新建文件,以下:
不是說只有一份打包的配置文件麼?咋還多了那麼多文件呢?是這樣,雖然咱們是業餘的,但咱也想作得專業一點對吧(有利於對配置進行擴展管理)!
咱們看 config/index.js
有什麼?
webpack.lib.conf.js
中。
再看看build/webpack.base.conf.js
裏面的關鍵配置:
entry
和
output
會被
webpack.lib.conf.js
覆寫;
rules
定義一系列loader的轉換規則,其中eslint的校驗就是在這裏定義了一個
eslint-loader
。
最後看一眼build/webpack.lib.conf.js
配置:
entry
的規則是,根據傳參值(components)分別走不一樣的入口文件,一種只有一個
./src/index.js
,這個是UI對外註冊的入口文件(這使得咱們能夠引入整個UI);另外一種是各個UI組件的註冊入口文件(這使得咱們能夠按需引入組件);
先給你們貼圖直觀感覺下源碼的目錄結構:
那實際打包的時候走的是哪種呢?真相是都走!在build-lib.js
中,執行了三次打包,打包輸出效果以下:
前面紮好了馬步,終於到修煉招式的階段了! 咱們都知道,在應用某個插件的時候須要通過下面代碼的調用:
import Ange from 'ange-ui'
Vue.use(Ange)
複製代碼
好奇下Vue.use
在作什麼處理呢?它其實就是註冊/安裝這個插件,根據use內部的定義,它經過調用install方法去註冊插件,那麼,Ange就必須是一個Function
(會被use當作是install
方法調用)或者是一個包含了install
方法的Object
。
道理我都懂,但是install
方法裏面到底寫些什麼?
試想一下,咱們但願在項目的任意位置都能引用這個插件,那咱們的每個組件是否是要在全局註冊?好比經過下面這種方式全局註冊組件:
Vue.component('pagination', pagination)
複製代碼
沒錯,install
方法內部就是批量地全局註冊組件。
首先咱們按照下圖的方式新建目錄和文件:
在 src目錄的index.js文件中定義install
方法:
import './scss/ange.scss' // 引入組件樣式表,也可讓用戶在使用的時候自行引入
import components from './components'
function install(Vue, opts = {}) {
Object.values(components).forEach((each) => {
Vue.component(each.name, each)
})
}
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
version: '1.0.0',
install,
...components
}
複製代碼
核心邏輯install就是對全部的組件循環註冊在全局。components目錄的 index.js 則是逐個對外暴露組件對象,其次每個組件也有一個 index.js ,它的做用是爲當前組件注入install方法。理所固然地,install
裏面是將該組件註冊在全局,因而咱們能夠按需引用組件。
組件開發的通用模板
<template>
<component :is="'button'"></component>
</template>
<script>
export default {
name: 'ag-button',
props: {}
}
</script>
複製代碼
component是vue的內置組件,is
參數設置成button
,代表最終渲染的html是button
標籤,咱們也能夠直接使用button標籤,但咱們的按鈕組件不必定是button,還多是a標籤,爲了更好的拓展,這裏使用component。
聲明組件參數
export default {
name: 'ag-button',
props: {
// 按鈕類別
primary: Boolean,
secondary: Boolean,
dashed: Boolean,
link: Boolean,
// 按鈕狀態
color: {
type: String,
validator (val) {
return new Set(['success', 'warn', 'danger']).has(val)
}
},
// 按鈕尺寸
size: {
type: String,
validator (val) {
return new Set(['large', 'normal', 'small']).has(val)
}
},
// 圖標按鈕
icon: String,
// 圓形按鈕(通常結合圖標按鈕使用)
circle: Boolean,
// 外鏈按鈕
external: Boolean,
// 異步按鈕
loading: Boolean
}
}
複製代碼
完善組件模板
<template>
<component :is="tag" class="ange-btn" :class="[ btnSize, color, { 'default': isDefault, 'primary': primary, 'secondary': secondary, 'dashed': dashed, 'link': link, 'icon': icon, 'circle': circle }]" @click="$emit('click', $event)" :disabled="loading">
<span class="ange-btn-content">
<!-- 圖標按鈕依賴 ag-icon 組件 -->
<ag-icon v-if="icon" :icon="icon" />
<slot /> <!-- 插槽接收按鈕文本 -->
</span>
</component>
</template>
<script> export default { // ... computed: { tag () { return this.external ? 'a' : 'button' }, isDefault() { const type = [this.primary, this.secondary, this.dashed, this.link] return type.every((each) => !each) }, btnSize() { return this.size || 'normal' } } } </script>
複製代碼
剩下的工做就是寫好樣式表了,你能夠選擇直接寫在vue文件裏面,也能夠新建_scss/scss_樣式表。
組件應用及效果(在線查看)
以上,便開發好一個button組件了,執行一下node build-lib.js
或者npm run build:lib
(如今package.json聲明script)就能夠打包這個UI框架,而後再將其發佈到npm平臺(若是你想...)
在線查看 Ange UI Docs 寫好文檔是一個庫不可或缺的部分,寫的過程經過實際應用各組件,還能夠對其進行測試校驗。前面說到,咱們的文檔要基於vuepress開發,簡潔的Markdown寫法,非常方便。這裏一篇 指南 能夠很好地幫助你,它告訴了你如何搭建架構,寫好配置以及部署上線,或者參考我這個 倉庫 的配置。
假設docs/views/button.md
是你的button
組件的文檔頁面,要如何引用你的組件?
button
組件:
import '@scss/ange.scss'
import Button from '@component/button'
Vue.use(Button)
複製代碼
至此,文檔也就寫好了!
最後的最後,按照 vuepress doc 部署到你的github倉庫上就能夠了!
本文經過button組件從0到1的開發,深刻淺出闡述了Vue UI框架的開發流程,你對Vue.js的理解越深,組件的功能越複雜,你就會用到更多的高級用法。經過自研UI框架,咱們也有很大的收穫:
PS:CSS實際上是UI開發中佔比很重的部分,你們按照本身的風格組件化開發就好。給你們推薦幾個很棒的配色網站:
最後,但願你們也能多多去嘗試,這個青銅自研UI庫的故事到這裏就結束了。
The end.