1. 程式人生 > >前端框架vue.js詳解

前端框架vue.js詳解

Vue.js 是一個JavaScriptMVVM庫,是一套構建使用者介面的漸進式框架。

摘要

2016年最火的前端框架當屬Vue.js了,很多使用過vue的程式設計師這樣評價它,“vue.js兼具angular.js和react.js的優點,並剔除了它們的缺點”。授予了這麼高的評價的vue.js,也是開源世界華人的驕傲,因為它的作者是位中國人–尤雨溪(Evan You)。

Vue.js 是一個JavaScriptMVVM庫,是一套構建使用者介面的漸進式框架。它是以資料驅動和元件化的思想構建的,採用自底向上增量開發的設計。相比於Angular.js,Vue.js提供了更加簡潔、更易於理解的API,使得我們能夠快速地上手並使用Vue.js。

除錯外掛

在vue除錯方面,可以選擇安裝chrome外掛vue Devtools。開啟vue專案,在console控制檯選擇vue面板。在Devtools工具中,可以選擇元件,檢視對應元件內的資料資訊。也可以選擇Vuex選項,檢視該專案內Vuex的狀態變數資訊。

UI 元件庫

在vue元件庫方面,個人不推薦使用UI元件庫,畢竟自己造輪子的過程還是很有成就感的。當然,如果更重視開發效率,並且選擇了vue2.0作為前端框架,那麼餓了麼推出的Element元件就是一個很不錯的選擇。其github專案(https://github.com/ElemeFE/element)更新比較頻繁,雖然專案會有些不穩定,但是目前為止element就是最好的支援vue2.0的UI元件。就像它的口號一樣,“快速成型,就為讓你少加班”。

vue、React、Angular1 對比

效能對比

在Angular1中,在scope作用域中每一次資料變化,會觸發watcher的重新計算,angular對常用的dom事件,xhr事件等做了封裝, 在裡面觸發進入angular的digest流程。在digest流程裡面,會從rootscope開始遍歷, 檢查所有的watcher。並且,如果一些 watcher 觸發另一個更新,髒檢查迴圈(digest cycle)可能要執行多次。Vue則沒有這個問題,因為它使用基於依賴追蹤的觀察系統並且非同步佇列更新,資料的變化都是獨立處罰的,除非資料之間有明確的依賴關係。

vue官方宣稱vue的渲染效能優於react。為了有理有據讓人信服,vue開發團隊建立了一個簡單的對比效能的專案(https://github.com/chrisvfritz/vue-render-performance-comparisons),它負責渲染10000個列表項100次。Vue官方將每一個參照專案都分別執行 20 次並取最好的結果結果如下圖:

由此可見,Vue的效能是遠好於Angular1,並且稍微優於React的。

社群拓展對比

Angular1的背後是Google,所以社群基礎是不需要擔心的,從Tutorial到StackOverflow的問題數量都可以反映出生態系統很完整。Angular1之後的2.0版本幾乎是一個推翻重做的框架,對於使用了1.X版本的專案,想要平滑的升級過渡到2.0版本應該是非常困難的。

現在Angular2的線上應用數量還不算太多,主流編碼還是以1.X版本居多。這個版本化巨大的差異也間接影響到了開發者對於angular的信心。

Vue和React都有強大的社群支援。React有狀態管理庫Flux、ReduxVue,相應的,Vue有vuex。

Vue 和 React 都提供了強大的路由庫來應對大型應用。然而Vue的路由庫和狀態管理庫都是由官方維護支援的。

React 則是選擇把這些問題交給社群維護,因此建立了一個更分散的生態系統。但相對的,React 的生態系統相比 Vue 更加繁榮。

此外,Vue 提供了Vue-cli 腳手架,包括了Webpack,Browserify,甚至路由庫,能讓你非常容易地構建專案。

學習陡峭度對比

在指令與元件方面,Vue中將指令和元件分得更清晰。指令只封裝 DOM 操作,而元件代表一個自給自足的獨立單元,有自己的檢視和資料邏輯。在 Angular1 中兩者有不少相混的地方。在API與框架設計方面,angular1都比vue要複雜的多。就個人感覺而言,angular1和React的學習曲線會相對陡峭一些,而vue的編碼方式會更趨近於前端開發者的程式設計習慣。

因為vue的作者是中國人,vue的官方網站、教程和api肯定是最完善、最易懂的。此外,每次大版本的釋出,都會伴隨著詳盡的遷移說明文件,包含了很多詳盡的闡述以及許多遷移的例子,甚至還有遷移工具。Angular的開發團隊你們就不覺得臉紅麼…

Vue的使用非常的簡單,建立一個本地的 .html 檔案,然後通過如下方式引入 Vue:

這樣就生成了vue的hello world應用。

渲染能力對比

ReactNative能使你用相同的元件模型編寫有本地渲染能力的 APP(iOS 和 Android)。能同時跨多平臺開發,對開發者是非常棒的。為了彌補這方面的不足,在2016年9月舉辦的JSConf2016期間,vue.js的作者尤雨溪宣佈加盟Weex團隊擔任技術顧問,雙方將進行更緊密的合作,共建開發生態圈。

Weex 是阿里的跨平臺使用者介面開發框架,Weex 的 JavaScript 框架執行時用的就是 Vue。在此之後,在 Weex 的幫助下,使用 Vue 語法開發的元件不僅僅可以執行在瀏覽器端,還能被用於開發 iOS 和 Android 上的原生應用。

Vue.js 的作者尤雨溪表示:“Weex選擇Vue作為其JavaScript執行時框架是讓我非常高興的一件事。Vue的元件開發模式已經被web開發者社群廣泛 認可,而把Vue的開發體驗拓展到原生平臺則是我一直想做但沒有餘力去做的事情。一想到Weex將能讓開發者們用Vue的語法去寫跨 Web/Android/iOS三端的通用元件,就讓我很興奮。”

vue的缺點

Vue就這麼好,難道沒有缺點嗎?當然有,vue雖然在16年非常火爆,但是相比於angular和react,不論是成熟度還是社群活躍度都還不是對手。此外,Vue明確聲明瞭自己放棄了對IE8的支援。再看看現在的招聘網站上,有多少寫了需要有angular經驗,而又有多少寫了需要vue經驗,就可見vue的影響力相比於angular和react還差的很遠。

vue全家桶及專案架構

Vue有著名的全家桶系列,包含了vue-router(http://router.vuejs.org),vuex(http://vuex.vuejs.org), vue-resource(https://github.com/pagekit/vue-resource)。再加上構建工具vue-cli,就是一個完整的vue專案的核心構成。

vue-router路由

推薦使用npm工具來安裝vue-router

npm install vue-router

通過import匯入並定義Vue模組、vue-router模組和需要使用的元件,在本例中,分別是Goods、Ratings和Seller元件。最後,如果在一個模組化工程中使用它,必須要通過 Vue.use() 明確地安裝路由功能。

import Vue from’vue’ importRouter from’vue-router’import Goods from ‘@/components/goods/goods’; import Ratings from ‘@/components/ratings/ratings’; import Seller from ‘@/components/seller/seller’;Vue.use(Router); // 需要import Vue和Router,不然會報錯undefined

通過const router= new VueRouter()來定義一個路由,並傳入對應的配置,包括路徑path和元件components。

最後,在使用newVue來建立和掛載vue根例項的時候,記得要通過 router配置引數注入路由,即在router中export出來的路由物件,從而讓整個應用都有路由功能。

vuex狀態管理

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。如前面所提到的,Vuex 已經整合到 Vue 的官方除錯工具vue Devtools,可以輕鬆的檢視專案中的Vuex狀態變化情況。

假設有這樣一個場景:我們的專案規模比較大,有多個父元件,每個父元件同時又包含多個子元件。如何保持對所有時間的追蹤將變得很困難。到底哪個事件是哪個元件派發的,哪個元件該監聽哪個事件?父元件將變得和子元件耦合越來越嚴重,因為它需要明確的派發和監聽子元件的某些事件。專案邏輯分散在各個元件當中,很容易導致邏輯的混亂,不利於我們專案的維護。

這就是 Vuex 用來解決的問題。 Vuex 的四個核心概念分別是:

The state tree:Vuex 使用單一狀態樹,用一個物件就包含了全部的應用層級狀態。至此它便作為一個『唯一資料來源(SSOT)』而存在。這也意味著,每個應用將僅僅包含一個 store 例項。單狀態樹讓我們能夠直接地定位任一特定的狀態片段,在除錯的過程中也能輕易地取得整個當前應用狀態的快照。

Getters:用來從 store 獲取 Vue 元件資料。

Mutators:事件處理器用來驅動狀態的變化。

Actions:可以給元件使用的函式,以此用來驅動事件處理器 mutations

Vuex和簡單的全域性物件是不同的,當Vuex從store中讀取狀態值的時候,若狀態發生了變化,那麼相應的元件也會高效的更新。並且,改變store中狀態的唯一途徑就是提交commit mutations。這樣便於我們跟蹤每一次狀態的變化。只要發生了狀態的變化,一定伴隨著mutation的提交。

讓我們來看一個最簡單的vuex例子:

安裝 Vuex 之後,讓我們來建立一個 store。建立過程直截了當——僅需要提供一個初始 state 物件和一些 mutations:

現在,你可以通過 store.state 來獲取狀態物件,以及通過 store.commit 方法觸發狀態變更:

vue-resource介紹

Vue-resource有體積小,支援IE9以上的瀏覽器,支援promise特性的特點。同樣推薦使用npm來安裝Vue-resource。

$ npm install vue-resource

在安裝並引入vue-resource後,可以基於全域性的Vue物件使用http,也可以基於某個Vue例項使用http。

在傳送請求後,使用then方法來處理響應結果,then方法有兩個引數,第一個引數是響應成功時的回撥函式,第二個引數是響應失敗時的回撥函式。

vue-resource的請求API是按照REST風格設計的,它提供了7種請求API:

· get(url,[options]) · head(url,[options]) · delete(url,[options]) · jsonp(url,[options]) · post(url,[body], [options]) · put(url, [body],[options]) · patch(url,[body], [options])

vue工程目錄結構

下圖是一個簡單的vue專案的大概結構,下面簡要介紹一下每個資料夾中一般都會存放哪些內容。

components/資料夾用來存放Vue 元件。個人建議,把每一個元件中使用到的image圖片放置到對應的元件子檔案目錄下,便於統一的管理

Node_modules/npm安裝的該專案的依賴庫 vuex/資料夾存放的是和 Vuex store 相關的東西(state物件,actions,mutations) router/資料夾存放的是跟vue-router相關的路由配置項 build/檔案是 webpack 的打包編譯配置檔案 static/資料夾存放一些靜態的、較少變動的image或者css檔案 config/資料夾存放的是一些配置項,比如伺服器訪問的埠配置等 dist/該資料夾一開始是不存在,在我們的專案經過 build 之後才會產出 App.vue根元件,所有的子元件都將在這裡被引用 index.html整個專案的入口檔案,將會引用我們的根元件 App.vue main.js入口檔案的 js 邏輯,在webpack 打包之後將被注入到 index.html 中

vue中less的應用

在vue專案中一樣可以使用less預編譯,只是需要使用npm安裝less-loader外掛。安裝完成後,在vue中的css模組進行簡單的配置,這樣就可以直接使用less來編寫樣式表了。在打包編譯的時候,會自動生成對應的css樣式。

vue合例項講解Vue核心功能

Vue的功能有很多,很難一一進行詳細的解釋。下面根據在工作中的專案例項,結合程式碼解釋一下vue的幾大核心功能。

計算屬性

假設有如下的購物車結算場景,使用者選中商品的總金額是根據商品數量、選中商品種類數 和商品單價來變化的。然而,數量、選中種類數量和單價這幾個物件都是根據使用者選擇而動態變化的,如果在前端模版中為了計算最終商品總額,放入這幾個動態變化的變數(商品數量、商品單價、選中商品種類),會讓這個邏輯變得複雜難以維護。在這種情況下,模版便不再簡潔清晰。Vue給出了此種場景的解決方案,在任何複雜的邏輯,vue都推薦使用計算屬性。

如上圖所示,在html中,我們只需要使用{{totalPrice}}這個計算屬性就可以來表示最終的商品總額。我們不需要關注這個變數的數值變化,totalPrice這個變數的邏輯寫在對應的computed計算屬性中。

也許會有疑問,這個計算屬性和定義一個method方法不是差不多麼?這兩者最大的區別是計算屬性是基於它的依賴進行快取的。計算屬性只有在它的相關依賴發生變化時才會重新計算求值。在本例中,只有當選擇商品的價格price和數量count發生變化時,這個計算屬性totalPrice才會重新計算新的值。這就意味著,只要totalPrice這個值沒有發生變化,多次訪問該計算屬性會立即返回之前的計算結果,而不必再次執行計算。

模版語法

Vue.js 使用了基於 HTML 的模版語法,允許開發者宣告式地將 DOM 繫結至底層 Vue 例項的資料。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循規範的瀏覽器和 HTML 解析器解析。Vue的模版語法包括了使用雙大括號插入文字、使用v-html插入純HTML內容、使用v-bind插入物件、類似angular的v-if、v-show、v-for指令、以及過濾器等等。

元件化

元件(Component)是 Vue.js 最強大的功能。元件可以封裝可重用的程式碼,通過傳入物件的不同,實現元件的複用。

舉一個簡單的組建例子,我們首先編寫一個star元件,它就是一個普通的star.vue檔案。它的作用就是簡單實現了一個五角星。

如何在其他的vue檔案中使用這個star元件呢?如下圖所示,首先通過import引入star元件物件,並在想使用star元件的vue檔案中宣告註冊star元件。現在就可以愉快的通過標籤來在該vue檔案中任意地方使用star元件了。在你想展示一個五角星的地方,使用一個star標籤,就可以輕鬆完成這個功能。

元件例項的作用域是孤立的。這意味著不能在子元件的模板內直接引用父元件的資料。要讓子元件使用父元件的資料,我們需要通過子元件的props選項。如本例所示,子元件star要顯式的使用props選項宣告它期待獲得的資料。在這裡就是指的“size”和“score”兩個變數。我們可以通過父級給子元件star傳入大小和數值這兩個物件,來實現對子元件的定製化。

過渡效果

Vue 在插入、更新或者移除 DOM 時,提供多種不同方式的應用過渡效果,可以用簡單的幾行程式碼實現酷炫的過渡效果。Vue 提供了 transition 的封裝元件,在使用v-if、v-show等方法使得transition內部dom元素髮生變化時,可以給任何元素和元件新增 entering/leaving 過渡。

當v-show中內容發生變化時,transition元件中的元素會發生狀態的改變,在應用了transition封裝後,Vue會自動識別目標元素是否應用了CSS過渡效果動畫,如果有,會在合適的時機新增 entering/leaving的class來實現該過渡效果。

下圖所示是一個簡單的過渡效果的例子,需要將想實現過渡效果的元素放在transition標籤中包裹,通過name=“slide-fade”來宣告過渡效果名稱,並在對應的vue檔案中新增過渡效果 的css樣式,這樣就可以簡單的完成該元素的過渡效果。

總結

根據不完全統計,包括餓了麼、蘇寧易購、美團、天貓、Laravel、htmlBurger等國內外知名大公司都在使用vue進行新專案的開發和舊專案的前端重構工作。

此外,vue + vuex+ axios + vue-router + webpack + es6 + less 的專案架構成為了越來越多大公司的第一選擇。