前端開發中,隨着業務的增多,出於效率的考慮,咱們對於組件化開發的需求也愈來愈迫切。最近公司也在推行組件化,參考其餘的組件庫的思路,我用 vue 作了一個組件化的 demo vueui-m 在這裏記錄下。(目前還不完善,僅做爲一個 demo)javascript
Vue.js 2.0
Webpack
Gulp
PostCSS
ES6/ES5css
CSS 首先要解決的是命名的問題。團隊開發組件的過程當中,要按照必定的約定,保證組件命名不會衝突。同時也要讓組件使用者可以清晰的瞭解命名的含義。這裏採用了 BEM 命名法。BEM 的意思就是塊(block)、元素(element)、修飾符(modifier),是由Yandex團隊提出的一種前端命名方法論。
關於 BEM 命名法,舉個例子。html
.block{} .block__element{} .block--modifier{}
這裏的 block 元素爲塊元素,它的後代元素在塊元素後面加兩個下劃線,表示是它的後代。不一樣狀態的元素在後面加兩個英文狀態下的破折號。
下面假設有個名爲 m-page 和 m-button 的元素。其中 m-button-group 是一個單獨的元素,不屬於 m-button 後代,因此是單個破折號。更詳細的信息能夠自行搜索。前端
<!-- 不一樣後代 --> <div class="m-page"> <div class="m-page__header"></div> <div class="m-page__body"></div> <div class="m-page__footer"></div> </div> <!-- 不一樣狀態 --> <div class="m-button-group"> <div class="m-button"></div> <div class="m-button--primary"></div> <div class="m-button--success"></div> <div class="m-button--cancel"></div> </div>
實際的開發過程當中,能夠將這種命名規範和其餘的實踐相結合,來適應自身項目。
可是,這種命名方法在寫 CSS 時,手動寫較長的命名效率會比較低。結合 postcss-bem 插件,可以幫咱們解決這個問題。
通過配置,咱們可以這樣寫 CSS,完美解決問題。vue
/*咱們寫的格式*/ @component-namespace m { @b page { @e header { @m gray { background-color: #ccc; } } } } /*插件幫咱們生成的*/ .m-page__header--gray { background-color: #ccc; }
同時,項目中使用了 cssnext 進行開發。cssnext 支持多種新特性,包括變量命名等。具體的能夠參考這裏。
結合 PostCSS,咱們可以在項目中使用 cssnext 的語法。我這裏使用了餓了麼的postcss-salad插件處理這個問題。它整合了一些經常使用的功能,包括定義函數等功能。java
使用 Babel 轉譯 es6,不用多說。
另外在命名組件的過程當中,有些組件會和原生 HTML 標籤衝突,咱們能夠加一個前綴,好比 button 組件,命名爲 mbutton 便可解決。git
單元測試使用 Karma + Mocha + Chai,對組件進行單元測試。Demo中,因爲時間緣由,暫時只寫了部分的單元測試用例。
端到端測試使用 Nightwatch。目前暫未編寫端到端測試用例。==es6
使用 Webpack 和 Gulp 對咱們寫好的組件進行打包。
出於可維護的角度,咱們的 Vue 組件和 CSS 在編寫的時候就分爲兩個目錄。而後打包的時候對它們分開打包。
對於 Vue 組件,使用 Webpack 進行生成的時候,把 output 的 libraryTarget 設置爲 'umd',使得產出的 JS 同時支持 AMD 和 CMD 規範。同時,咱們生成的文件,會生成模塊單獨的文件以及一個總體的 Main.js。
對於 CSS,和 JS 相似,會生成一個總體的 Main.css 和 模塊單獨對應的 CSS 文件。github
咱們打包產出的文件產出在 lib 目錄下。 lib 目錄下有 components 和 styles 兩個目錄,分別對應 JS 和 CSS。
這個圖片是發佈到 npm 上的目錄結構。npm
這個是 lib 目錄下的內容。目前 Main.js 在 main 目錄下,之後應該單獨拿出來。main.css 在 styles 目錄下和模塊的 CSS 文件同級。
src 目錄和 lib 目錄相似。
JS
/* umd格式,.js 結尾 */ //從總體文件中引入 import {Tab, MButton} from 'vueui-m' //從單個文件中引入 import Tab from 'vueui-m/lib/components/tab' import MButton from 'vueui-m/lib/components/mbutton' /* Vue 組件格式,.vue 結尾 */ //從總體文件引入 import {Tab, MButton} from 'vueui-m/src/components/main' //從單個文件中引入 import Tab from 'vueui-m/src/components/tab' import MButton from 'vueui-m/src/components/mbutton'
CSS
/* 引入總體文件 */ @import '~vueui-m/lib/styles/main.css' /* 引入單個文件 */ @import '~vueui-m/lib/styles/tab.css' @import '~vueui-m/lib/styles/m-button.css'
目前對於 JS 和 CSS 須要引入兩次,之後能夠引入 babel-plugin-component 插件,使得引入一個組件的時候不須要再手動引入對應的 CSS。
這個 demo 的完成,參考了一些別的組件庫的製做思路。
element-ui
vux
ant.design向他們表示感謝。