Vue組件庫 VV-UI 開始接受PR啦,有興趣小夥伴可以一起參與開源哦。
前言:
剛開源出來的VV-UI目前剛剛起步,組件不是很多,非常歡迎大家的pr和Star。
項目地址: https://github.com/VV-UI/VV-UI
演示地址: https://vv-ui.github.io/VV-UI/#/
目前組件庫已經引入meta-info
管理單頁面title meta link
等常用的seo問題。
回歸正題,如何搭建一套基於Vue的組件庫呢?
1. 環境準備
我們搭建組件庫,需要準備一系列環境,首先我們要考慮一下問題:
- 腳手架如何搭建
- 如何規劃目錄結構
- 如何編寫文檔
首先,對於腳手架環境的問題,目前已經有非常成熟的vue官方的腳手架,我們拿來用就好了
# 全局安裝 vue-cli $ npminstall --global vue-cli # 創建一個基於 webpack 模板的新項目 $ vue init webpack my-project # 安裝依賴,走你 $ cd my-project $ npm install $ npm run dev
接著我們看第二個問題,如何規劃好我們組建的目錄結構?首先我們需要有一個目錄存放組件,有一個目錄存放示例。所以我們要對vue-cli 生成的項目結構做一下改造:
. ... |-- examples // 原 src 目錄,改成 examples 用作示例展示 |-- packages //新增 packages 用於編寫存放組件 ... .
這樣的話 我們需要再把我們webpack配置文件稍作一下調整,首先是把原先的編譯指向src的目錄改成examples,其次為了 npm run build
能正常編譯 packages 我們也需要為 babel-loader 再增加一個編譯目錄:
{ test: /\.js$/, loader: ‘babel-loader‘, include: [resolve(‘examples‘), resolve(‘test‘), resolve(‘packages‘)] }
這樣我們搭建起來一個簡易的目錄結構。
rules: [ { test: /\.md$/, loader: ‘vue-markdown-loader‘ } ]
好了,我們可以開始嘗試寫文檔了,在 example/docs 目錄下新建 test.md。
# test
> Hello World
同時創建一個新的路由,指向我們的md文件:
{ path: ‘/test‘, name: ‘test‘, component: r => require.ensure([], () => r(require(‘../docs/test.md‘))) }
打開我們的瀏覽器http://localhost:8080/#/test
哈哈 真的成功了。別高興的太早.... 問題還在後面:我們期望的文檔不僅能編譯markdown,而且最好能識別demo代碼塊一方面做演示,一方面可以顯示演示代碼最好了,就像這樣:
那我們需要怎麽做呢?vue-mark-down 功能肯定不止這些!於是我們繼續閱讀它的文檔,發現其實他就是封裝了 markdown-it,支持 options 選項。這樣我們就可以為我們的markdown定義獨特的標識符,這裏我用 demo 標識需要顯示代碼塊的地方,所以我需要配置options 選項 :
const vueMarkdown = { preprocess: (MarkdownIt, source) => { MarkdownIt.renderer.rules.table_open = function () { return ‘<table class="table">‘ } MarkdownIt.renderer.rules.fence = utils.wrapCustomClass(MarkdownIt.renderer.rules.fence) return source }, use: [ [MarkdownItContainer, ‘demo‘, { // 用於校驗包含demo的代碼塊 validate: params => params.trim().match(/^demo\s*(.*)$/), render: function(tokens, idx) { var m = tokens[idx].info.trim().match(/^demo\s*(.*)$/); if (tokens[idx].nesting === 1) { var desc = tokens[idx + 2].content; // 編譯成html const html = utils.convertHtml(striptags(tokens[idx + 1].content, ‘script‘)) // 移除描述,防止被添加到代碼塊 tokens[idx + 2].children = []; return `<demo-block> <div slot="desc">${html}</div> <div slot="highlight">`; } return ‘</div></demo-block>\n‘; } }] ] }
這裏簡單的描述一下這段代碼是幹什麽的:首先把內容裏面vue片段編譯成html,用於顯示,另一方面用highlight來高亮代碼塊。demo-block
本身是我們定義好的組件:
<template> <div class="docs-demo-wrapper"> <div :style="{maxHeight: isExpand ? ‘700px‘ : ‘0‘}" class="demo-container"> <div span="14"> <div class="docs-demo docs-demo--expand"> <div class="highlight-wrapper"> <slot name="highlight"></slot> </div> </div> </div> </div> <span class="docs-trans docs-demo__triangle" @click="toggle">{{isExpand ? ‘隱藏代碼‘ : ‘顯示代碼‘}}</span> </div> </template>
這樣,我們的 test.md 便可以這麽去寫了:
2. 如何編寫組件
環境準備完畢,緊接著要開始編寫組件,考慮的是組件庫,所以我們竟可能讓我們的組件支持全局引入和按需引入,如果全局引入,那麽所有的組件需要要註冊到Vue component 上,並導出:
const install = function(Vue) {
if (install.installed) return;
components.map(component => Vue.component(component.name, component));
};
export default {
install
};
接著要實現按需加載,我們只需要單個導出組件即可:
import Button from ‘./button/index.js‘;
import Row from ‘./row/index‘
import Col from ‘./col/index‘
const components = [
Button,
Row,
Col
];
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,
Button,
Row,
Col
};
其次,我們還需要考慮一個問題:既然是單頁面應用,必然要去解決樣式沖突問題,如果組件內使用soped,那麽樣式就無法從組件內抽離出來,達不到可定制化主題顏色的目的。我們需要一套可以分離處理的樣式,可以自行編譯,可以相互不汙染。這時候css 的BEM規範就顯得尤為重要。如果你還不知道什麽是BEM 參考: http://www.w3cplus.com/css/css-architecture-1.html。
說到這裏,目前對BEM規範支持較好的插件就是postcss了,他允許我們配置BEM之間的連接符和縮寫:
{
"browsers": ["ie > 8", "last 2 versions"],
"features": {
"bem": {
"shortcuts": {
"component": "b",
"modifier": "m",
"descendent": "e"
},
"separators": {
"descendent": "__",
"modifier": "--"
}
}
}
}
這樣我們就可以把樣式單獨的抽離出來,通過gulp進行打包編譯:
gulp.task(‘compile‘, function() {
return gulp.src(‘./src/*.css‘)
.pipe(postcss([salad]))
.pipe(cssmin())
.pipe(gulp.dest(‘./lib‘));
});
最後生成我們的樣式代碼。
好了開始我們的測試:
import VVUI from ‘../packages/index‘
import ‘../packages/theme-default/lib/index.css‘
Vue.use(VVUI)
一切顯得那麽美好....
優化與不足
- 組件導出代碼暫不支持自動化生成:比如我們的組件index文件,每次添加組件都需要不斷地改寫,我們2*
可以嘗試進行webpack配置,npm run dev
的時候自動進行組件檢測,然後幫我們寫好導出代碼。 - 缺少單測
- 目錄結構劃分缺陷:目前所有內容僅支持中文,如果想要做到支持國際化,那麽還需要重新調整目錄結構。
- 發布tag: 需要編寫腳本支持tag發布
- 組件太少:文檔剛寫,組件還不是很多,慢慢去維護,相信會越來越多的組件,做業務的過程中也可以把常用的組件加進去,這樣更加方便自己以後的維護和學習
結語:
項目github地址:github
項目演示地址: 演示
歡迎 PR 一起維護,歡迎 Star
Vue組件庫 VV-UI 開始接受PR啦,有興趣小夥伴可以一起參與開源哦。