爲Vue2集成UIkit

引言:Vue只是爲咱們提供了一個很優秀的前端組件式開發框架,但單純依靠Vue是作不出一個漂亮的網頁應用的,甚至連「不難看」這個標準都達不到。這個時候藉助界面框架UIkit可以很好地解決這一問題。
本文出自《Vue2實踐揭祕》一書。css

  在實際開發中,還有不少經常使用組件,例如,分頁、按鈕、輸入框、導航欄、日期/時間選擇器、圖片輸入,等等。很明顯的是這些組件的通用性已不僅僅存在於一個項目內,而是全部的項目都須要!這是個比拼開發速度的年代,咱們已經沒有時間重複發明輪子了,最正確的選擇是使用界面框架,例如Bootstrap、UIkit、Foundation等來代替這種大量的重複性極強的界面樣式開發工做。html

UIkit

  Bootstrap已經有不少年曆史了,在業界的應用也至關廣泛,不管是前端開發或者後端開發,爲了能快速作一個不算太難看的界面,它天然成爲衆多工程師的選擇,包括我。多年下來,Bookstrap的改進實在是太緩慢了。不客氣地說,它基本上就沒讓咱們這些用戶感受它改進過,同質化嚴重,功能性組件一直不見增長,等等,都讓咱們只能是痛並用着。
  UIkit給咱們帶來了福音,不管從界面上的樣式,仍是實用組件的數目,甚至到易用性來講都要比Bootstrap好上一個層次。惟一的缺陷是它出生得比較晚,可選的主題樣式資源很少,畢竟還須要時間讓第三方社區來推進發展。但用它來作一個漂亮的交互性強的應用絕對是一個最佳的推薦方案。
  Vue社區上也有一些包裝UIkit的庫,如vuikit,但它的文檔實在太少了,甚至從一開始的安裝配套都作得很是差,基本上是脫離了UIkit的核心樣式包和核心腳本編寫的。雖然努力可嘉,但這種功能性複製的包建議仍是不要用,前端最耗不起的就是編譯包的大小。每一個引入的第三方包咱們都得吝嗇地測算一下得失,即便webpack能夠用chuck來分包,但也不能濫用,不然加載速度緩慢就是破壞使用體驗的最大因素。前端

安裝

  雖然在AngularJS、React和Vue的項目中jQuery歷來都是一個不受歡迎的庫。首先是它編譯出來後就很是大,並且影響咱們的MVVM思惟,容易由於圖方便而又回到jQuery那種直接操控DOM的死路上去。但jQuery的強大在於它的普及性,幾乎咱們能找到的不少優秀小組件都會有jQuery版本,甚至只有jQuery的版本。而UIkit正是其中一員,不能抗拒的話也只能學會享受。咱們得同時安裝jQuery、UIkit兩個庫:vue

$ npm i jquery uikit -D

配置

  咱們須要將jQuery和UIkit的引用以及一些字體的引用配置添加到webpack中(UIkit內置引用了Fontawesome字體庫),確保已安裝了url-loader這個庫,若是沒有安裝的話用如下指令進行安裝:node

$ npm i url-loader --D

  在webpack.config.js的module.rules配置中加入字體引用配置:jquery

rules: [
    // ... 省略
    {        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,        loader: 'url',        query: {            limit: 10000,            name: '[name].[hash:7].[ext]'
        }
    }
]

  固然,若是你採用vue-cli webpack模板來構造項目的話,能夠跳過以上的配置。
  UIkit的運行主要依賴於一個主樣式文件uikit.css、一個主題文件uikit.almost-flat.css(主題文件內置有三個可選項)和一個腳本文件uikit.js。使用UIkit時,須要在代碼中同時import它們才能讓webpack在編譯時正確地引用。界面包都是全局性的,那麼能夠選擇在main.js文件一開始加入引用:webpack

import 'jquery'import 'uikit'import 'uikit/dist/css/uikit.almost-flat.css'

  這樣寫就違反了在第2章工程化Vue.js開發中的一個配置約定,咱們不該該將「庫」或「依賴包」以全路徑方式引入到代碼文件中,而應該用webpack的resolve配置項,用別名來代替全路徑。如下是在webpack中配置UIkit的樣式引用別名:web

resolve: {    alias: {        'vue$': 'vue/dist/vue',        'uikit-css$': 'uikit/dist/css/uikit.almost-flat.css'
    }
}

  在main.js代碼內引入UIkit,代碼就變爲:vue-cli

import 'jquery'import 'uikit'import "uikit-css"

製做UIkit的Vue插件

  上述的寫法仍是不夠DRY,爲了使用一個包就得引入多個不一樣的依賴庫,這種作法實在很難看,此時咱們能夠選擇一個Vue的最佳作法,就是用插件形式來包裝這種零碎化的引入方式。在src根目錄下新建一個uikit.js的文件,而後用Vue的插件格式來進行包裝。如下代碼中直接向Vue實例注入了UIkit的一些經常使用的幫助方法:npm

import 'jquery'import 'uikit'import 'uikit-css'export default (Vue, options) {    // 向實例注入UIkit的對話框類方法
    Vue.prototype.$ui = {
        alert: UIkit.modal.alert
        confirm: UIkit.modal.confirm,
        prompt: UIkit.modal.prompt,
        block: UIkit.modal.block
    }
}

  完成uikit.js的編寫就能夠改寫main.js的內容了:

import UIkit from './uikit'Vue.use(UIKit)

  因爲對Vue.prototype進行了擴展,那麼就能夠像vue-resource那樣在每一個Vue實例內的this方法中注入一個$ui對象,用如下方法來顯示簡單的對話框:

methods: {
    delItem() {        this.$ui.confirm('您確認要刪除如下的數據嗎?', () => {            // 這裏編寫對數據進行刪除的代碼
        })
    }
}

  

       圖片描述

  上述的confirm方法有一個明顯的弱點,就是在回調時this上下文會指向window而不是Vue實例自己,這樣的話對於編碼的使用體驗就不好了。咱們能夠在插件內對confirm作一個修飾,將回調方法的this從新指向Vue實例:

Vue.prototype.$ui = {   // ... 省略
   confirm (question,callback,cancelCallback,options) {
        UIkit.confirm(question,        callback || callback.apply(this),
        cancelCallback || cancelCallback.apply(this),
        options)
   }

}

  apply函數是ECMA JavaScript的標準函數,用於更改調用方法上傳遞的上下文對象。上述代碼就是將回調函數的上下文強制替換爲當前的Vue實例,避免了回調上下文丟失而須要手工去定義變量,「hold住」原有this上下文的痛苦。

關於apply函數詳細說明能夠參考如下連接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply。

  如今的代碼是否是感受乾淨多了?那麼回過頭來看Vue的插件,在這裏面咱們不只能夠像上述代碼那樣單純地對Vue實例進行擴展,還能夠進行更多的全局化的處理。固然這裏的全局是指這個插件庫被引入Vue並調用use方法後,例如,咱們能夠將一些必要的組件或者指令混入插件方法內:

export default = (Vue, options) => {  // 1. 注入全局化的方法
  Vue.myGlobalMethod = () => {    // ...
  }  // 2. 進行必要組件的註冊
  Vue.component('html-editor', { 
    HtmlEditor
  })  // 3. 註冊一個全局化的指令標記
  Vue.directive('sortable', {
    bind (el, binding, vnode, oldVnode) {      // something logic ...
    }
    ...
  })  // 4. 注入一些組件的選項
  Vue.mixin({    created: function () {      // ...
    }
    ...
  })  // 5. 擴展實例
  Vue.prototype.$ui = {}

}

UIkit中的坑

  當運行以上的代碼後,會很沮喪地發現瀏覽器中總會出現UI.$爲空的異常,具體顯示以下:

Type error UI.$ is undefined.

  我曾嘗試過直接跳入UIkit的源代碼中查找UI.$,這個變量實際上是對jQuery的一個內部引用,準確地說這是在引用jQuery的腳本後由jQuery註冊到瀏覽器的window全局變量上的jQuery實例。估計是UIkit在生成加載代碼時變量的映射與初始化順序出現問題了。後來想了個辦法,直接在webpack.config.js配置內對全局變量進行改寫,具體代碼以下:

plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",            jQuery: "jquery",            "window.jQuery": "jquery",            "window.$": "jquery"
        })
]

  webpack.ProvidePlugin這個插件是用於JS代碼加載後在window上註冊全局變量的一個webpack插件,加入了以上的配置後程序就能正常運行了。最終幸運地從大坑中逃出生還!這樣UIkit就被集成到咱們的Vue項目中來了。
  本文出自《Vue2實踐揭祕》一書,點此連接可在博文視點官網查看此書。
                    圖片描述
  想及時得到更多精彩文章,可在微信中搜索「博文視點」或者掃描下方二維碼並關注。
                       圖片描述

相關文章
相關標籤/搜索