很久沒發文章.由於真的太忙太忙了,寫了一個組件庫,這一個組件庫都是下班時間搞的,由於真的是時間和精力有限花了一個多月才搞完,好屢次都想放棄,不知道是否是真的太菜了?這還用問,固然是!真正寫起來你纔會發現考慮的狀況太多了,邏輯會出問題,環境不一會也有問題了,沒法打包了,還要認真去編寫官網的demo和使用文檔javascript
若是你寫過一個UI庫(固然我指的不是隻有隻有一個button組件的庫,以前看不少文章,標題是搭建了vueUi庫,進去後發現只有一個button, my god!!!),這意味着你對,computed,watch,prop,slot,@slots,$scopedSlots,mixins,$emit,遞歸組件,做用域插槽
,至少是這些都熟練掌握,還包括你對一些組件邏輯的思考,基本的算法能力也不是不好,若是你寫過你就知道我說的對不對了,因此我鼓勵你們都造一個UI庫玩玩.
略複雜的我都已經標註來了,固然只是相對而言,目前我已經完成了這些(可直接點擊下邊超連接跳轉體驗):css
vue create nature-ui
module.exports = {
pages: {
index: {
entry: "examples/main.js"
}
}
}
複製代碼
|--packages
|----index.js
|----button
|------index.vue
複製代碼
index.vue很是簡單的內容:vue
<template>
<button>nature-ui</button>
</template>
<script>
export default {
name: 'nt-button'
}
複製代碼
好了如今再examples的App.vue中引入button下的index.vue,而後yarn serve啓動.若是啓動正常沒什麼問題的話,你應該能在頁面上看到這個buttonjava
別忘了,還有index.js,這個js的目的是爲了導出全部組件,從而讓別人在使用咱們的UI庫的時候.能夠引入以後,經過Vue.use的方式引入.git
後續全部的組件都會在這個index.js中導出組件:github
import Button from './button'
// 全部組件列表
const components = [
Button
]
// 定義 install 方法,接收 Vue 做爲參數
const install = function (Vue) {
// 判斷是否安裝,安裝過就不繼續往下執行
if (install.installed) return
install.installed = true
// 遍歷註冊全部組件
components.map(component => {
if (typeof component === 'undefined' || !component.name) return;
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,
...components
}
複製代碼
你們應該能夠看到像elementUI,iView這些比較優秀的UI庫都是進行了樣式分離的,這樣也很是的有利於往後樣式的管理和維護.web
好比個人nature-ui,是在packages下新建了nt-styles目錄,下邊的src目錄來專門存放個人全部的css文件.算法
這裏咱們使用市場上歡呼度最高最流行的BEM寫法來寫,也有一些別的文章記錄過BEM和vue-cli的項目進行集成的,可是這裏使用了最新的vue-cli3後,仍是略有一些不一樣的,坑我都已經替你們踩過了vue-cli
npm i postcss-salad precss -D
複製代碼
安裝完成以後,vue-cli3 的項目須要在項目根目錄的package.json中進行配置,新增:npm
"postcss": {
"plugins": {
"autoprefixer": {},
"postcss-salad": {
"browsers": [
"ie > 8",
"last 2 versions"
],
"features": {
"bem": {
"shortcuts": {
"component": "b",
"descendent": "e",
"modifier": "m"
},
"separators": {
// 這裏的符號須要與你的css語法進行對應,
"descendent": "__
"modifier": "_"
}
}
}
}
}
},
複製代碼
上邊的符號須要與你的css語法進行對應:
好比:
.nt-button__input_active
@b nt-button{
@e input{
@m active{
}
}
}
複製代碼
這樣纔是對應的,BEM語法只有class!如今就能夠徹底對BEM語法進行解析了,
首先全局安裝gulp:
npm install gulp -g
複製代碼
安裝gulp解析BEM語法所須要的編譯css須要的依賴
npm install gulp-cssmin gulp-rename gulp-concat gulp-postcss -D
複製代碼
在packages目錄下的nt-styles目錄中新建,gulpfile.js來對css進行編譯( 註釋都給各位加上了 ):
//gulp文件流:src表示源頭->pipe表示管道->dest表示終點
gulp.task('css', function () {
return gulp.src('./index.css')
.pipe(concat('nature.css')) //經過concat將css文件拼接成一個叫作style.css的文件
.pipe(
postcss([
require('autoprefixer'),
require('postcss-salad')({
"browsers": [
"ie > 8",
"last 2 versions"
],
"features": {
"bem": {
"shortcuts": {
"component": "b",
"descendent": "e",
"modifier": "m"
},
"separators": {
"descendent": "__",
"modifier": "_"
}
}
}
})
])
)
.pipe(cssmin()) //經過cssmin將上一步驟生產出的style.css去掉中間的空白,使他變成壓縮格式
.pipe(rename({
suffix: '.min' //rename只是給上一步驟產出的壓縮的styles.css重命名爲style.min.css
}))
.pipe(gulp.dest('../../lib/styles')) //dest方法把上一步驟產出的style.min.css輸出到「./dist/css」目錄下(gulp流的終點)
});
複製代碼
在package.json的scripts下,新增兩條命令:
// --target 後接的是你要打
"lib": "vue-cli-service build --target lib --dest lib packages/index.js",
"lib-css": "npx gulp css --gulpfile ./packages/nt-styles/gulpfile.js"
複製代碼
測試css,
首先給上邊的button加一個類,好比,nt-button_default;
在nt-styles目錄的src下,新建button.css,內容爲:
@b nt-button{
@m default{
background:red;
}
}
複製代碼
在App.vue中引入這個css.若是看到按鈕變爲紅色,那麼,恭喜閣下,BEM解析已經生效了,
萬事俱備了,如今先給你的UI庫想一個文質彬彬的名字,而後發佈到npm去先佔一個坑位吧,否則可能等你寫完了發現,名字已經被佔用了,好比不少類名都是根據UI庫名字來命名的,到時候就很差改嘍~
如今分別執行:
npm run lib
npm run lib-css
複製代碼
全部的文件都已經在lib目錄下生成了~
去npm先註冊一個帳號吧,有郵箱認證的,郵箱被填錯
而後回到項目,在package.json下新增:
"main": "lib/nature-ui.umd.min.js",
複製代碼
這個的目的是爲了指定你的UI庫的入口,而後就是:
npm login //回車輸入用戶名和密碼
npm publish // 每次publish的版本號都要比上一次高
複製代碼
我一直以來的觀念就是最重要的不是代碼,而是思想,也給有須要的朋友提供一個參考
全部的組件編寫必定是先肯定
而不是邊寫邊定義,這個很是重要,邏輯部分最好先理清思路,否則會特別浪費時間
全部組件有須要的你們能夠自行看代碼,每次寫以前想清楚便可
好比日期組件,確定是須要知道某年某月是多少天,這個月的最後一天是幾號,這個月的第一天是星期幾,這個面板從第幾格開始是不可點的,諸如此類,列個todolist或者思惟導圖,而後看每一個需求應該如何去突破,應該用哪一個api,各個擊破,最後只要一組合就能夠,這樣思路就會很是清晰了,而不是上來就是一把梭就開始寫,這些只是我我的的一些技巧,固然,對你未必有用
由於最開始寫的時候,出現過返工的狀況,寫了一部分,發現從最開始路就走錯了,這樣讓我很是懊惱
這個我還沒作,真的是一我的時間和精力有限,計劃明天或者後天專門發一篇關於單元測試的文章,這個真的頗有必要!
若是以爲對您有幫助,給個star鼓勵下我疲憊的心靈,謝謝你們了~
最近建了一個2羣(541643529)供你們吹水,相親,討論技術,分享學習資料使用,一切均可以問,用東哥的話來說,進了這個羣,咱們就是兄弟!