【蛻變】搭建史上真正沒有注水的VueUI庫Nature-UI,包含18個複雜組件

前言

很久沒發文章.由於真的太忙太忙了,寫了一個組件庫,這一個組件庫都是下班時間搞的,由於真的是時間和精力有限花了一個多月才搞完,好屢次都想放棄,不知道是否是真的太菜了?這還用問,固然是!真正寫起來你纔會發現考慮的狀況太多了,邏輯會出問題,環境不一會也有問題了,沒法打包了,還要認真去編寫官網的demo和使用文檔javascript

官網預覽,PC端點擊體驗

github

若是你寫過一個UI庫(固然我指的不是隻有隻有一個button組件的庫,以前看不少文章,標題是搭建了vueUi庫,進去後發現只有一個button, my god!!!),這意味着你對,computed,watch,prop,slot,@slots,$scopedSlots,mixins,$emit,遞歸組件,做用域插槽,至少是這些都熟練掌握,還包括你對一些組件邏輯的思考,基本的算法能力也不是不好,若是你寫過你就知道我說的對不對了,因此我鼓勵你們都造一個UI庫玩玩.
略複雜的我都已經標註來了,固然只是相對而言,目前我已經完成了這些(可直接點擊下邊超連接跳轉體驗):css

基於vue-cli3環境搭建

結構改造

  • 初始化項目vue create nature-ui
  • 改造項目目錄
  • src修改成examples,這個裏邊就是能夠供你進行測試組件,和編寫官方文檔的,下邊會介紹
  • 根目錄新增packages目錄,存放全部的組件
  • 根目錄新增vue.config.js,目的是爲了改造項目入口,改成:examples/main.js
module.exports = {
    pages: {
        index: {
            entry"examples/main.js"
        }
    }
}
複製代碼
  • 在packages下新建button文件夾,button下新建index.vue,並在packages下新建index.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 
}
複製代碼

CSS樣式分離

你們應該能夠看到像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對css文件進行打包

首先全局安裝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

在package.json的scripts下,新增兩條命令:

  1. lib是爲了打包全部的組件,打包成一個js,若是不出意外,執行後你的根目錄會生成一個lib目錄下邊有一堆js和js.map文件,你只須要關心xxxxx.umd.min.js,好比個人就是nature-ui.umd.min.js
  2. 第二條命令顯而易見就是爲了打包css
// --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.js

npm先註冊一個帳號吧,有郵箱認證的,郵箱被填錯

而後回到項目,在package.json下新增:

 "main""lib/nature-ui.umd.min.js",
複製代碼

這個的目的是爲了指定你的UI庫的入口,而後就是:

npm login //回車輸入用戶名和密碼
npm publish // 每次publish的版本號都要比上一次高
複製代碼

組件核心邏輯心得

我一直以來的觀念就是最重要的不是代碼,而是思想,也給有須要的朋友提供一個參考

全部的組件編寫必定是先肯定

  1. props:屬性
  2. slot:插槽內容分發
  3. event: 組件事件

而不是邊寫邊定義,這個很是重要,邏輯部分最好先理清思路,否則會特別浪費時間

全部組件有須要的你們能夠自行看代碼,每次寫以前想清楚便可

好比日期組件,確定是須要知道某年某月是多少天,這個月的最後一天是幾號,這個月的第一天是星期幾,這個面板從第幾格開始是不可點的,諸如此類,列個todolist或者思惟導圖,而後看每一個需求應該如何去突破,應該用哪一個api,各個擊破,最後只要一組合就能夠,這樣思路就會很是清晰了,而不是上來就是一把梭就開始寫,這些只是我我的的一些技巧,固然,對你未必有用

由於最開始寫的時候,出現過返工的狀況,寫了一部分,發現從最開始路就走錯了,這樣讓我很是懊惱

單元測試

這個我還沒作,真的是一我的時間和精力有限,計劃明天或者後天專門發一篇關於單元測試的文章,這個真的頗有必要!

若是以爲對您有幫助,給個star鼓勵下我疲憊的心靈,謝謝你們了~

最近建了一個2羣(541643529)供你們吹水,相親,討論技術,分享學習資料使用,一切均可以問,用東哥的話來說,進了這個羣,咱們就是兄弟!

相關文章
相關標籤/搜索