Vue 發(fā)布十年了!你知道我這十年是怎么過(guò)的嗎?
2014 年 2 月 3 日,Vue 在 Hacker News 上首次亮相。十年后的今天,Vue 已經(jīng)成為使用最廣泛的前端框架之一,擁有了一個(gè)非常豐富的生態(tài)系統(tǒng)。本文來(lái)梳理一下 Vue.js 十年以來(lái)的重要里程碑!
圖片
尤雨溪,無(wú)疑是 Vue.js 背后的靈魂人物。早在 2013 年,他還在 Google 工作,便接觸到了 Google 團(tuán)隊(duì)開(kāi)發(fā)的強(qiáng)大前端框架 Angular。他對(duì) Angular 的產(chǎn)生了興趣,但覺(jué)得它并不完美。因此,決定打造一款更為輕量且用戶友好的前端框架,這就是我們今天所熟知的 Vue.js。自此,Vue 的故事就開(kāi)始了...
圖片
庫(kù)階段(2013-2015)
在 2013 年至 2015 年期間,可以將 Vue 視為處于庫(kù)階段。那么,庫(kù)和框架的區(qū)別到底是什么呢?庫(kù)更多地被視為嵌入到已有的體系中,只是簡(jiǎn)單地拿來(lái)使用。而框架則定義了更廣泛的一套工程實(shí)踐,遵循一定的最佳實(shí)踐,并使用配套的工具來(lái)遵循一整套規(guī)范。因此,當(dāng)時(shí)的Vue只是一個(gè)庫(kù)。
圖片
- 2013.12:發(fā)布第一個(gè)以“Vue.js”命名的版本(0.6.0),在此之前的版本都叫 Seed;
- 2014.02:第一次在 HackerNews 上公開(kāi)發(fā),公開(kāi)后的第一周獲得了 400+ Github Star;
- 2014.10:第一次實(shí)現(xiàn) Vue SFC 單文件組件(vueify),使用 Browserify 打包;
- 2014.11:第一次完全重寫(xiě)(0.11),考慮如何讓它更適合用在生產(chǎn)環(huán)境中。
庫(kù)階段的設(shè)計(jì)重點(diǎn):
- 基于 ES5 的 getter/setters 和原生 JavaScript 對(duì)象實(shí)現(xiàn)響應(yīng)式系統(tǒng),當(dāng)時(shí)的設(shè)計(jì)重點(diǎn)就是滿足個(gè)人設(shè)計(jì)和實(shí)現(xiàn)上的想法和興趣;
- 基于響應(yīng)式系統(tǒng)實(shí)現(xiàn)模版數(shù)據(jù)綁定(MVVM);
- 設(shè)計(jì)重點(diǎn)就是能像 JQuery 一樣可以直接通過(guò)<script>標(biāo)簽直接引用的簡(jiǎn)單庫(kù),這種方式不會(huì)對(duì)其他方面產(chǎn)生意見(jiàn)和限制。
庫(kù)階段的特征:
- Vue 還不算一個(gè)框架;
- 當(dāng)時(shí)的 API 受到了 Backbone/Ractive 的影響
響應(yīng)式系統(tǒng)和組件實(shí)例有很強(qiáng)的耦合,所有響應(yīng)式的內(nèi)容都需要通過(guò)在this上做操作來(lái)實(shí)現(xiàn),這樣的實(shí)現(xiàn)比較直觀,容易理解,符合基于class思考的思維模式,但是會(huì)影響邏輯復(fù)用;
直到 0.11 版本才引入 Mixins(混入);
- 該階段還在摸索完善模板語(yǔ)法和作用域規(guī)則,每個(gè)版本的模板語(yǔ)法都會(huì)有比較重大的變動(dòng),并且作用域規(guī)則不是很明確;
- 基于 DOM 的渲染機(jī)制;
- 模板和編譯后的 JavaScript 之間沒(méi)有對(duì)應(yīng)性,當(dāng)時(shí)的 Vue 并沒(méi)有“編譯”過(guò)程;
- 當(dāng)時(shí)的 Vue 的實(shí)現(xiàn)通過(guò)把模板直接實(shí)例化為 DOM 樹(shù);
- 遍歷實(shí)例化之后的 DOM 樹(shù),在遍歷過(guò)程中實(shí)現(xiàn)數(shù)據(jù)綁定;
- 類似于現(xiàn)在 petite-vue 的實(shí)現(xiàn),它是在 Vue 3 之后,重新將 Vue 1 的實(shí)現(xiàn)構(gòu)成一個(gè)更輕量的實(shí)現(xiàn),可以將 petite-vue 認(rèn)為是 Vue 1的一個(gè)新的展現(xiàn), 把 Vue 1 的實(shí)現(xiàn)以更現(xiàn)代的方式去提供出來(lái),其更適用于更輕量化的、不需要很多工程化介入的場(chǎng)景。
框架階段(2015-2016)
2015-2016 年,Vue 就進(jìn)入了框架階段,以 1.X 版本為目標(biāo)。
圖片
框架階段的重要里程碑:
- 2015.08:發(fā)布第一版 Vue Router;
- 2015.09:基于0.11、0.12版本開(kāi)始開(kāi)發(fā) Vue 1.0,主要是完善模板語(yǔ)法;
- 2015.10.26:發(fā)布 Vue 1.0,代號(hào)為 Evangelion;
- 2015.12:發(fā)布第一版 vue-cli,它更像是一個(gè)拉模板的工具,將配置好的模板拉到本地;
- 2016.03:發(fā)布第一版 Vuex。
框架階段的設(shè)計(jì)重點(diǎn):
- 穩(wěn)定模板語(yǔ)法和作用域的設(shè)計(jì):
確定了 v-bind、v-on 和對(duì)應(yīng)簡(jiǎn)寫(xiě)的語(yǔ)法;
第一次引入了 v-for(取代了 v-repeat);
將 Vue 項(xiàng)目的涵蓋范疇擴(kuò)大到了單頁(yè)面應(yīng)用(SPA)框架
- SPA 路由;
- 狀態(tài)管理;
- 工具鏈:實(shí)現(xiàn)了單文件組件的熱更新支持和Scoped CSS。
通用框架階段(2016-2019)
2016-2019 年,Vue 進(jìn)入了通用框架階段,以 2.X 版本為目標(biāo)。
圖片
通用框架階段的重要里程碑:
- 2016.03:第一次明確提出“漸進(jìn)式框架”的概念;
- 2016.04:開(kāi)始開(kāi)發(fā) Vue 2.0,尤雨溪正式離職開(kāi)始全職開(kāi)發(fā) Vue;
- 2016.10.01:發(fā)布 Vue 2.0,代號(hào)為 Ghost in the Shell;
- 2016.11:發(fā)布 Vue 2.1,代號(hào)為 Hunter X Hunter,引入了作用域插槽;
- 2017.02:發(fā)布 Vue 2.2,代號(hào)為 Initial D,SSR 支持基于路由的代碼分割,每個(gè)路由的代碼可以懶加載;
- 2017.04:發(fā)布 Vue 2.3,代號(hào)為 JoJo,SSR 支持基于路由的資源預(yù)加載;
- 2017.07:發(fā)布 Vue 2.4,代號(hào)為 Kill la Kill,SSR 完整異步組件支持,可以在 SSR 應(yīng)用的任何地方使用異步組件,引入了部分優(yōu)化的 SSR 編譯輸出;
- **2017.10:發(fā)布 Vue 2.5,代號(hào)為 Level E,**該版本引入了新的錯(cuò)誤處理鉤子函數(shù)、改進(jìn)了模板表達(dá)式錯(cuò)誤消息和選項(xiàng)類型檢查、提供更好的TypeScript類型聲明支持。
- **2019.2:**發(fā)布 Vue 2.6,代號(hào)為 Macross,該版本實(shí)現(xiàn)了新的v-slot語(yǔ)法、在函數(shù)式組件中添加了scopedSlots、為生命周期鉤子和v-on處理程序提供了同步和異步錯(cuò)誤處理、支持動(dòng)態(tài)指令參數(shù)、添加了Vue.observable()方法用于創(chuàng)建可觀察對(duì)象、在$scopedSlots上暴露了所有普通插槽等。
- 2018.01-08:開(kāi)發(fā) Vue Cli 3.0,進(jìn)一步擴(kuò)展框架的邊界,將工具鏈視為框架的一部分;實(shí)現(xiàn)針對(duì) SPA 的高度集成的工具鏈,有插件機(jī)制,開(kāi)箱即用,集成 TypeScript 、單元測(cè)試、ESLint 等;
Vue 2.0 階段的設(shè)計(jì)重點(diǎn):
- Vue 的第二次徹底重寫(xiě),目標(biāo)是改進(jìn)代碼的架構(gòu),提高其長(zhǎng)期的可維護(hù)性,目前來(lái)看 2.0 版本的可維護(hù)性依然是相當(dāng)可以的;
- 引入了將模板編譯為 Virtual DOM 渲染函數(shù)的編譯流程,也就是在 2.0 才引入了“模板編譯”的概念;
- 基于 Virtual DOM 的服務(wù)端渲染(SSR),先編譯為 Virtual DOM 的渲染函數(shù),生成 Virtual DOM,再將 Virtual DOM 字符串化,類似于 React 的服務(wù)端渲染;
- 基于 Virtual DOM 的 跨端渲染(整合 Weex,NativeScript);
- 結(jié)合類型系統(tǒng):
在源碼中使用 Flow 定義類型;
直到現(xiàn)在,2.x 版本的 TypeScript 類型定義都需要手動(dòng)維護(hù),而不是從源代碼中生成的,這也是在 Vue 3 中使用 TypeScript 進(jìn)行重寫(xiě)的原因之一。
這個(gè)階段有一個(gè)重要的 demo:vue-hackernews-2.0:
- 使用 Webpack + SFC + Vue Router + Vuex + SSR 實(shí)現(xiàn);
- 第一個(gè)完整展示 Vue 2 SSR 架構(gòu)的 demo,包含了相關(guān)的 Webpack 配置,單文件組件如何針對(duì)客戶端和服務(wù)端進(jìn)行不同的編譯配置,如何在重構(gòu)的架構(gòu)中使用路由、狀態(tài)管理等;
- 利用這個(gè) demo 做了很多 Vue 2 SSR 功能的開(kāi)發(fā),通過(guò)這個(gè) demo 來(lái)測(cè) Vue 2 SSR 在實(shí)際開(kāi)發(fā)中是否易用;
- 這個(gè) demo 更重要的意義是啟發(fā)了上層的 SSR 框架,比如 Nuxt.js,Nuxt 最初就參照這個(gè) demo 實(shí)現(xiàn),并吸取了 Next.js 的經(jīng)驗(yàn)。
編譯/運(yùn)行時(shí)混合階段(2019-至今)
2019年至今,Vue 進(jìn)入了編譯/運(yùn)行時(shí)混合階段。雖然 2.0 階段引入了編譯,但是 2.0 的編譯和運(yùn)行時(shí)的結(jié)合是非常淺的結(jié)合,編譯器編譯出 Virtual DOM 渲染函數(shù)就到此為止了,編譯器對(duì)運(yùn)行時(shí)是怎么樣的并沒(méi)有太多概念,而運(yùn)行時(shí)對(duì)于編譯器也是沒(méi)有概念的,這樣很多優(yōu)化空間就被浪費(fèi)了。所以 3.0 階段的主要目標(biāo)就是讓編譯器和運(yùn)行時(shí)都屬于框架的一部分,它們本身就是耦合的。 在耦合的前提下,讓編譯器為運(yùn)行時(shí)提供更多的信息,讓運(yùn)行時(shí)知道編譯器提供的信息。
圖片
編譯/運(yùn)行時(shí)混合階段的重要里程碑:
- 2018.09:在 Vue.js London 宣布 Vue 3 的開(kāi)發(fā)計(jì)劃;
- 2018.09 - 2019.05:調(diào)研階段;
- 2019.05:實(shí)現(xiàn)基于編譯優(yōu)化 Virtual DOM 性能的新策略;
- 2019.08:提出 Composition API RFC;
- 2020.01:發(fā)布 Vue 3.0 alpha 版本;
- 2020.04:發(fā)布 Vue 3.0 beta 版本,引入了完全優(yōu)化的 SSR 編譯輸出,如果組件是用模板寫(xiě)的,那它的 SSR 編譯輸出不存在任何 Virtual DOM 的開(kāi)銷,所有能做成字符串拼接的地方都做成了字符串拼接;
- 2020.04 - 2021.02:繞道開(kāi)發(fā)了 Vite。
- 2020.09:Vue 3.0 穩(wěn)定版正式發(fā)布;
- 2021.06:發(fā)布 Vue 3.1 版本,提供 Migration Build,使用可以兼容 Vue 2 的用法讓用戶更方便的升級(jí);
- 2021.08:發(fā)布 Vue 3.2 版本,引入了 <script setup>。
- 2022.01:Vue 3 正式切換為默認(rèn)版本,此時(shí) Vue 3 框架范疇內(nèi)的工具都準(zhǔn)備完畢;
- 2022.02:發(fā)布全新的 Vue 3 文檔;
- 2022.06:發(fā)布 Vue 2.7,進(jìn)一步彌補(bǔ)了 2 和 3 之間的斷層,提供了一個(gè) 2->3 更緩和的升級(jí)流程。不過(guò),如果現(xiàn)在的 Vue 2 項(xiàng)目很穩(wěn)定,沒(méi)必要為了升級(jí)而升級(jí);
- 2023.05:發(fā)布 Vue 3.3,主要針對(duì)開(kāi)發(fā)者體驗(yàn)進(jìn)行了改進(jìn),特別是在使用 TypeScript 時(shí)的 SFC <script setup>,解決了在使用 TypeScript 時(shí)存在的許多長(zhǎng)期困擾問(wèn)題。
- 2023.12:發(fā)布 Vue 2.7.16,版本號(hào)為 Swan Song,意為絕唱。這是 Vue 2 的最后一個(gè)版本。
- 2023.12:發(fā)布 Vue 3.4,該版本重寫(xiě)了模板解析器。新的解析器將速度提高了 2 倍,顯著提升了整體性能。此外,響應(yīng)性系統(tǒng)也經(jīng)過(guò)了重構(gòu),使得 effect 觸發(fā)更為精確和高效。
- 2023.12.31:Vue 2 正式停止維護(hù),團(tuán)隊(duì)將把精力全部放在維護(hù) Vue 3 上。
Vue 3.0 重構(gòu)初期的重心:
- 提高瀏覽器的最低支持要求,使用現(xiàn)代 ES 語(yǔ)法和功能;
- 全面提升系統(tǒng);
- 改善類型系統(tǒng)的整合;
- 改善在大型應(yīng)用中的可擴(kuò)展性。2018年慢慢開(kāi)始有有較大型企業(yè)、項(xiàng)目開(kāi)始使用Vue,讓 Vue 遇到了新的挑戰(zhàn),在實(shí)際的場(chǎng)景中,之前的 Vue 設(shè)計(jì)在比較大的團(tuán)隊(duì)協(xié)作的場(chǎng)景中存在可維護(hù)性上的問(wèn)題,希望在 Vue 3 中找到這些問(wèn)題的解決方案。
Composition API 的意義:
- Vue 的用例越來(lái)越多地進(jìn)入企業(yè)、大型項(xiàng)目領(lǐng)域;
- Options API 在可擴(kuò)展性方面有明顯的上限,對(duì)于重構(gòu)龐大、臃腫的組件有很大的難度,不能輕松的進(jìn)行邏輯的重新組織。而 Composition API 對(duì)邏輯的可維護(hù)、組合、復(fù)用提供了很好的解決方案;
- 因?yàn)?Composition API 更多的依賴函數(shù)調(diào)用,所以對(duì)類型系統(tǒng)更友好;
- 提供靈活且可維護(hù)的邏輯組合/復(fù)用。
Vite 的意義:
- Vite 大幅優(yōu)化了開(kāi)發(fā)體驗(yàn);
- 將和框架沒(méi)有耦合的工具鏈職責(zé)剝離,交給一個(gè)更大的社區(qū)去維護(hù),這樣也會(huì)樣 Vue 的體驗(yàn)變得更好;
- 減少 Vue 本身的框架范疇和維護(hù)負(fù)擔(dān):Vue CLI -> create-vue
整體趨勢(shì)就是向編譯/運(yùn)行時(shí)混合模式進(jìn)化:
- 同一份模板,不同的編譯輸出:
在瀏覽器中:輸出高度優(yōu)化的 Virtual DOM 渲染函數(shù);
在 SSR 中:輸出 buffer + 字符串拼接;
將來(lái):Vapar mode(不依賴 Virtual DOM 的渲染代碼,獲得更好的性能)
- 在單文件組件中引入更多的語(yǔ)法糖:
- <script setup>;
- v-bind():實(shí)現(xiàn)動(dòng)態(tài) CSS 的綁定;
- Reactivity Transform
面向未來(lái)
Vue 團(tuán)隊(duì)目前在重點(diǎn)開(kāi)發(fā) Vapor mode。這是一種正在試驗(yàn)中的編譯策略,其靈感來(lái)源于 Solid。對(duì)于相同的 Vue SFC,與當(dāng)前基于虛擬 DOM 的編譯結(jié)果相比,Vapor Mode 能夠生成性能更高、內(nèi)存使用更少、運(yùn)行時(shí)支持代碼更少的 JavaScript 輸出。它的目標(biāo)是通過(guò)編譯為更高效的 JavaScript 來(lái)提升應(yīng)用的性能。當(dāng)在應(yīng)用級(jí)別使用時(shí),Vapor Mode 可以完全去除虛擬 DOM,從而減小應(yīng)用的包大小,進(jìn)一步優(yōu)化應(yīng)用的性能。
Vue 2 已經(jīng)停止維護(hù),這是一個(gè)時(shí)代的結(jié)束,也是一個(gè)新時(shí)代的開(kāi)始,2024 年對(duì) Vue 來(lái)說(shuō)將是激動(dòng)人心的一年!