Vue簡史

題記

「誰掌握了過去,誰就掌握了將來」——喬治.奧威爾javascript

前言

發端於2013年的我的項目,已然成爲全世界三大前端框架之一,在中國大陸更是前端首選。html

它的設計思想、編碼技巧也被衆多的框架借鑑、模仿。前端

學習研究Vue的演進,對於前端同窗來講,是提升自身認識和水平的法門。vue

紀略

Ø 2013年,在Google工做的尤雨溪,受到Angular的啓發,從中提取本身所喜歡的部分,開發出了一款輕量框架,最初命名爲Seed。java

Ø 同年12月,這粒種子發芽了,改名爲Vue,版本號是0.6.0。react

Ø 2014.01.24,Vue正式對外發布,版本號是0.8.0。git

Ø 發佈於2014.02.25的0.9.0,有了本身的代號:Animatrix,這個名字來自動畫版的《駭客帝國》,此後,重要的版本都會有本身的代號。es6

Ø 0.12.0發佈於2015.06.13,代號Dragon Ball(龍珠),這一年,Vue迎來了大爆發,Laravel 社區(一款流行的 PHP 框架的社區)首次使用 Vue(我也是在這個論壇上認識Vue的),Vue在JS社區也打響了知名度。github

Ø 1.0.0 Evangelion(新世紀福音戰士)是Vue歷史上的第一個里程碑。同年,vue-router(2015-08-18)、vuex(2015-11-28)、vue-cli(2015-12-27)相繼發佈,標誌着 Vue從一個視圖層庫發展爲一個漸進式框架。不少前端同窗也是從這個版本開始成爲Vue的用戶。vue-router

Ø 2.0.0 Ghost in the Shell(攻殼機動隊)是第二個重要的里程碑,它吸取了React的Virtual Dom方案,還支持服務端渲染。

Ø 就在不久前,Vue發佈了2.6.0 Macross(超時空要塞),這是一個承前啓後的版本,由於在它以後,3.0.0也呼之欲出了。

1.0

Vue最初的目標是成爲大型項目的一個良好補充。設計思想是一種「漸進式框架」,淡化框架自己的主張下降框架做爲工具的複雜度,從而下降對使用者的要求。

相較於以前的版本,1.0的主要改進點是:

1. 提供指令的縮寫

針對v-bind和v-on提供縮寫形式:

<!-- full syntax -->
<a v-bind:href="url"></a>
<!-- shorthand -->
<a :href="url"></a>

<!-- full syntax -->
<button v-bind:disabled="someDynamicCondition">Button</button>
<!-- shorthand -->
<button :disabled="someDynamicCondition">Button</button>複製代碼

<!-- full syntax -->
<a v-on:click="doSomething"></a>
<!-- shorthand -->
<a @click="doSomething"></a>複製代碼

2. 清理精簡所提供的接口

此時Vue的目標仍是但願做爲輕量級框架,成爲大型項目的補充(這些大型項目也許已經有本身的前端框架了,如Angular)。

首先清理的固然是那些基本不用的API。

3. 提升初始化的渲染效率

將v-repeat指令換成了v-for指令。同時優化了這個指令的渲染,效率提高了一倍。

4. 兩個官方工具的加強:vue-loadervueify

除了這些,咱們還知道,Vue中數據綁定採用的是數據劫持的方式,使用Object的defineProperty方法。和當時主流的Angular使用的事件觸發的髒檢查是不一樣的。


這類作法將開發者與直接的DOM操做隔離開來,使得開發者可以更專一於業務邏輯,同時也改變了開發者的思惟方式。

2.0

2016年10月1日發佈的2.0版本對Vue作了大幅度的重構,性能有了很大的提升,也爲往後的跨端發展打下了基礎。

1. Virtual DOM

在1.0的時候,Vue和Angular同樣,都是把template扔給瀏覽器解析渲染,而後遍歷DOM樹,提取節點,綁定數據。

用過1.0版本的同窗可能還有印象,若是你使用了Moustache語法來展現內容,會在頁面上看到一閃而過的」{{…}}」

2.0借鑑了React的作法,先將template編譯爲render函數,render函數返回Virtual DOM對象,而後再交由patch函數,調用瀏覽器接口,渲染出DOM。

Virtual DOM並不能保證渲染效率必定高於直接調用原生DOM接口(例如innerHTML),還須要配合diff,儘可能縮小刷新的範圍。

除了渲染效率,這種作法還爲Vue可以擴展到多端打下了基礎。Virtual DOM實際上可視爲一種通用的數據格式,若是小學生能看懂VDOM的話,你可讓他們在操場上用團體操擺出個網頁來

2. Render函數

前面已經提到了Render函數的做用,這裏再也不贅述。不過我以爲Render函數最大的意義在於:

a) 經過Vue提供的構建工具,將template的編譯從運行時放到了編譯時,提升了運行時的效率

b) 能夠只使用Vue的runtime版本,減少文件體積。

3. 服務端渲染

服務端渲染的目的主要有兩點:

a) 更好的SEO,因爲搜索引擎爬蟲抓取工具能夠直接查看徹底渲染的頁面。

b) 更快的首屏渲染速度。特別是對於網路速度慢或者運行緩慢的設備,無需等待全部的js都下載和解析完成才渲染頁面,而是在服務端渲染好直接發送給客戶端渲染頁面。


2.6

在2.6發佈以前的很長一段時間,Vue核心團隊都在忙着vue-cli3.0的開發,積攢了很多需求,一直到2019.02.04,發佈了2.6版本。

這個版本主要的改動涉及:語法更新,性能提高,以及向計劃中的3.0靠攏。

1. slot語法更新

提供了一個新的指令:v-slot,用來代替slot組件,以統一slot和scoped slot。

2. 異步錯誤處理

和2.5相比,errorCaptured 鉤子和全局的 errorHandler 配置項如今也會處理 v-on 偵聽函數中拋出的錯誤了。另外,若是組件的生命週期鉤子或事件handler中有異步操做,那麼能夠經過返回一個 Promise 的方式來讓 Vue 處理可能存在的異步錯誤。

3. 動態指令參數

參看官網的例子,如今指令的參數能夠是動態值,若是參數值爲 null,則綁定和監聽器會被移除。

<!-- full syntax -->
<a v-bind:href="url"> ... </a>

<!-- shorthand -->
<a :href="url"> ... </a>

<!-- shorthand with dynamic argument (2.6.0+) -->
<a :[key]="url"> ... </a>複製代碼

<!-- full syntax -->
<a v-on:click="doSomething"> ... </a>

<!-- shorthand -->
<a @click="doSomething"> ... </a>

<!-- shorthand with dynamic argument (2.6.0+) -->
<a @[event]="doSomething"> ... </a>複製代碼

4. 編譯器警告位置信息

2.6 版本開始,大多數模板編譯警告消息如今都帶有源碼位置信息:


5. 顯式建立獨立的響應式對象

2.6 引入了一個新的全局 API,能夠用來顯式地建立響應式對象

constreactiveState =Vue.observable({  count:0})複製代碼

生成的對象能夠直接用在計算屬性和 render 函數中,在被改動時觸發相應的更新。

6. 新 ES 模塊構建,可直接導入使用

<script type="module">
import Vue from 'https://unpkg.com/vue/dist/vue.esm.browser.js'
  
new Vue({
  // ...
})
</script>複製代碼

7. 讓 nextTick 恢復使用 Microtask

在 2.5 版本中,開發團隊作出了一個內部調整:若是更新是在 v-on 事件處理程序中觸發的,則會致使 nextTick 使用 Macrotask(而不是 Microtask)來讓更新進入隊列。最初這麼作是爲了修復一些瀏覽器的邊界狀況,但反過來又致使了不少其餘問題。在 2.6 版本中,開發團隊爲原始問題找到了一個更簡單的修復方案,這樣咱們就能夠在任何狀況下恢復 nextTick 使用 Microtask。

8. this.$scopedSlots 函數統一返回數組

在 render 函數中,scoped slot 經過 this.$scopedSlots 暴露爲函數。在以前版本,調用 scoped slot 函數會根據父組件傳入內容返回單個 VNode 或 VNode 數組。這種設計其實是一種疏忽,由於它返回值的類型不肯定,可能會致使意外的邊界狀況。

在 2.6 版本,scoped slot 函數確保只返回 VNode 數組或 undefined。

3.0

3.0是很是大的重構,源碼使用TypeScript重寫,而且還有許多使人期待的新特性:

1. Virtual DOM徹底重構

編譯器承擔了更多的責任,將以前一些在runtime時作的工做挪了過來:

a) 組件快速路徑+單一類型+子類型檢測:


b) 優化slot的編譯,避免無謂的父/子節點重渲染

普通的 slot 是在父組件的渲染函數中生成的,所以當一個普通的 slot 所依賴的數據發生變化時,首先觸發的是父組件的更新,而後新的 slot 內容被傳到子組件,觸發子組件更新。

相比之下,scoped slot 在編譯時生成的是一個函數,這個函數被傳入子組件以後會在子組件的渲染函數中被調用。這意味着 scoped slot 的依賴會被子組件收集,那麼當依賴變更時就只會直接觸發子組件更新。

c) 靜態內容和靜態屬性提取

當編譯器發現這些靜態屬性的時候,就會直接提取這部分的靜態屬性做爲實例屬性的一部分,在後面的數據比較中直接忽略這部分靜態屬性,以提高性能。


d) 內聯事件函數的提取

2. 使用Proxy代替defineProperty

defineProperty監聽不到對象屬性的增刪、數組元素和長度的變化,同時會在vue初始化的時候把全部的Observer都創建好,才能觀察到數據對象屬性的變化。

而proxy能夠作到監聽對象屬性的增刪和數組元素和長度的修改,還能夠監聽Map、Set、WeakSet、WeakMap,同時還實現了惰性的監聽,不會在初始化的時候建立全部的Observer,而是會在用到的時候纔去監聽。

3. 使用TypeScript重構

由於Flow爛尾了,而TypeScript又愈來愈好。

4. 自定義的Renderer API

這一點是爲了向多端擴展,咱們知道,如今Weex適配Vue採起的是fork的方式。3.0以後,這些native的適配層就能夠經過自定義渲染器的方式來擴展了。

5. 支持Time Slicing

目前時間切片還處於實驗階段。

Vue運行在瀏覽器的主線程,若是運行了一個很是耗費時間的操做,那麼瀏覽器會中止對用戶操做的響應,直到計算完畢。顯然這種用戶體驗是很是糟糕的,用戶還覺得瀏覽器已經掛掉了。在有了Time Slicing支持後,Vue將會限制本身的執行時間,只在一個時間片斷內運行,這個時間片斷被稱爲「幀」,默認狀況下一幀的時間是16ms,對於小型計算任務來講基本足夠了,而一秒鐘能夠運行62.5幀,有60幀左右的刷新率,瀏覽器對用戶的響應將會是比較順滑的了。

參考資料

維基百科:Vue.js

State of Vue.js report 2017 中文版

vuejs.org/2015/10/26/…

Vue 2.0 is Here!

The Progressive Framework

Vue2.0 中,「漸進式框架」和「自底向上增量開發的設計」這兩個概念是什麼?

Vue做者尤雨溪:Vue 2.0,漸進式前端解決方案

javascript實現數據雙向綁定的三種方式

網上都說操做真實 DOM 慢,但測試結果卻比 React 更快,爲何?

Vue 服務端渲染技術

ES6入門:Proxy

ES6入門:Reflect

ES6黑科技實踐--proxy,reflect

VUE3.0的這些改進你會期待嗎

全面改革:解讀 Vue 3.0 的變化

實現雙向綁定Proxy比defineproperty優劣如何

Time Slicing Demo

如何評價React的新功能Time Slice 和Suspense?

學習React Fiber架構,理解如何實現時間分片(Time Slicing)和 Suspense.

徹底理解React Fiber

擴展閱讀

中譯名

一句話介紹

Animatrix

駭客帝國動畫版

錫安究竟是不是真的

Blade Runner

銀翼殺手

影史最佳科幻片,催生了賽博朋克這一科幻流派的產生

Cowboy Bebop

星際牛仔

由於東京電視臺單方面認爲動畫存在較大的尺度問題而並無讓這部動畫如期播完。

Dragon Ball

龍珠/七龍珠

鳥山明的表明做

Evangelion

新世紀福音戰士

日本動畫史上的里程碑,被公認爲日本歷史中最偉大的動畫之一

Ghost in the shell

攻殼機動隊

故事設定在2029年,快來了

Hunter x Hunter

全職獵人

連載二十年,休刊無數次

Initial D

頭文字D

仍是周杰倫演的好看

JoJos Bizarre Adventure

JOJO的奇妙冒險

我儘可能避免戰鬥,可是我從不逃避

Kill la Kill

斬服少女

Level E

靈異E接觸

開啓了富堅義博休刊習慣的罪惡之源

Macross

超時空要塞

作工精良的精品

相關文章
相關標籤/搜索