為Vue2集成UIkit
引言:Vue隻是為我們提供了一個很優秀的前端組件式開發框架,但單純依靠Vue是做不出一個漂亮的網頁應用的,甚至連“不難看”這個標準都達不到。這個時候借助界麵框架UIkit能夠很好地解決這一問題。
本文出自《Vue2實踐揭秘》一書。
在實際開發中,還有很多常用組件,例如,分頁、按鈕、輸入框、導航欄、日期/時間選擇器、圖片輸入,等等。很明顯的是這些組件的通用性已不單單存在於一個項目內,而是所有的項目都需要!這是個比拚開發速度的年代,我們已經沒有時間重複發明輪子了,最正確的選擇是使用界麵框架,例如Bootstrap、UIkit、Foundation等來代替這種大量的重複性極強的界麵樣式開發工作。
UIkit
Bootstrap已經有很多年曆史了,在業界的應用也相當普遍,無論是前端開發或者後端開發,為了能快速做一個不算太難看的界麵,它自然成為眾多工程師的選擇,包括我。多年下來,Bookstrap的改進實在是太緩慢了。不客氣地說,它基本上就沒讓我們這些用戶感覺它改進過,同質化嚴重,功能性組件一直不見增加,等等,都讓我們隻能是痛並用著。
UIkit給我們帶來了福音,無論從界麵上的樣式,還是實用組件的數目,甚至到易用性來說都要比Bootstrap好上一個層次。唯一的缺陷是它出生得比較晚,可選的主題樣式資源不多,畢竟還需要時間讓第三方社區來推動發展。但用它來做一個漂亮的交互性強的應用絕對是一個最佳的推薦方案。
Vue社區上也有一些包裝UIkit的庫,如vuikit,但它的文檔實在太少了,甚至從一開始的安裝配套都做得非常差,基本上是脫離了UIkit的核心樣式包和核心腳本編寫的。雖然努力可嘉,但這種功能性複製的包建議還是不要用,前端最耗不起的就是編譯包的大小。每個引入的第三方包我們都得吝嗇地測算一下得失,即使webpack可以用chuck來分包,但也不能濫用,否則加載速度緩慢就是破壞使用體驗的最大因素。
安裝
雖然在AngularJS、React和Vue的項目中jQuery從來都是一個不受歡迎的庫。首先是它編譯出來後就非常大,而且影響我們的MVVM思維,容易因為圖方便而又回到jQuery那種直接操控DOM的死路上去。但jQuery的強大在於它的普及性,幾乎我們能找到的很多優秀小組件都會有jQuery版本,甚至隻有jQuery的版本。而UIkit正是其中一員,不能抗拒的話也隻能學會享受。我們得同時安裝jQuery、UIkit兩個庫:
$ npm i jquery uikit -D
配置
我們需要將jQuery和UIkit的引用以及一些字體的引用配置添加到webpack中(UIkit內置引用了Fontawesome字體庫),確保已安裝了url-loader這個庫,如果沒有安裝的話用以下指令進行安裝:
$ npm i url-loader --D
在webpack.config.js的module.rules配置中加入字體引用配置:
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文件一開始加入引用:
import 'jquery'
import 'uikit'
import 'uikit/dist/css/uikit.almost-flat.css'
這樣寫就違反了在第2章工程化Vue.js開發中的一個配置約定,我們不應該將“庫”或“依賴包”以全路徑方式引入到代碼文件中,而應該用webpack的resolve配置項,用別名來代替全路徑。以下是在webpack中配置UIkit的樣式引用別名:
resolve: {
alias: {
'vue$': 'vue/dist/vue',
'uikit-css$': 'uikit/dist/css/uikit.almost-flat.css'
}
}
在main.js代碼內引入UIkit,代碼就變為:
import 'jquery'
import 'uikit'
import "uikit-css"
製作UIkit的Vue插件
上述的寫法還是不夠DRY,為了使用一個包就得引入多個不同的依賴庫,這種做法實在很難看,此時我們可以選擇一個Vue的最佳做法,就是用插件形式來包裝這種零碎化的引入方式。在src根目錄下新建一個uikit.js的文件,然後用Vue的插件格式來進行包裝。以下代碼中直接向Vue實例注入了UIkit的一些常用的幫助方法:
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實踐揭秘》一書,點此鏈接可在博文視點官網查看此書。
想及時獲得更多精彩文章,可在微信中搜索“博文視點”或者掃描下方二維碼並關注。
最後更新:2017-04-26 13:02:02