vue學(xué)習(xí)篇——vue框架和其他框架對(duì)比(官網(wǎng))

DSL (Domain-Specific Language 領(lǐng)域特定語(yǔ)言)

React

React 和 Vue 有許多相似之處,它們都有:

使用 Virtual DOM
提供了響應(yīng)式 (Reactive) 和組件化 (Composable) 的視圖組件。
將注意力集中保持在核心庫(kù),而將其他功能如路由和全局狀態(tài)管理交給相關(guān)的庫(kù)。

運(yùn)行時(shí)性能

優(yōu)化

在 React 應(yīng)用中,當(dāng)某個(gè)組件的狀態(tài)發(fā)生變化時(shí),它會(huì)以該組件為根,重新渲染整個(gè)組件子樹(shù)。

如要避免不必要的子組件的重渲染,你需要在所有可能的地方使用 PureComponent,或是手動(dòng)實(shí)現(xiàn) shouldComponentUpdate 方法。同時(shí)你可能會(huì)需要使用不可變的數(shù)據(jù)結(jié)構(gòu)來(lái)使得你的組件更容易被優(yōu)化。

然而,使用 PureComponent 和 shouldComponentUpdate 時(shí),需要保證該組件的整個(gè)子樹(shù)的渲染輸出都是由該組件的 props 所決定的。如果不符合這個(gè)情況,那么此類優(yōu)化就會(huì)導(dǎo)致難以察覺(jué)的渲染結(jié)果不一致。這使得 React 中的組件優(yōu)化伴隨著相當(dāng)?shù)男闹秦?fù)擔(dān)。

在 Vue 應(yīng)用中,組件的依賴是在渲染過(guò)程中自動(dòng)追蹤的,所以系統(tǒng)能精確知曉哪個(gè)組件確實(shí)需要被重渲染。你可以理解為每一個(gè)組件都已經(jīng)自動(dòng)獲得了 shouldComponentUpdate,并且沒(méi)有上述的子樹(shù)問(wèn)題限制。

Vue 的這個(gè)特點(diǎn)使得開(kāi)發(fā)者不再需要考慮此類優(yōu)化,從而能夠更好地專注于應(yīng)用本身。

HTML & CSS

在 React 中,一切都是 JavaScript。不僅僅是 HTML 可以用 JSX 來(lái)表達(dá),現(xiàn)在的潮流也越來(lái)越多地將 CSS 也納入到 JavaScript 中來(lái)處理。這類方案有其優(yōu)點(diǎn),但也存在一些不是每個(gè)開(kāi)發(fā)者都能接受的取舍。

Vue 的整體思想是擁抱經(jīng)典的 Web 技術(shù),并在其上進(jìn)行擴(kuò)展。我們下面會(huì)詳細(xì)分析一下。

JSX vs Templates

在 React 中,所有的組件的渲染功能都依靠 JSX。JSX 是使用 XML 語(yǔ)法編寫(xiě) JavaScript 的一種語(yǔ)法糖。

使用 JSX 的渲染函數(shù)有下面這些優(yōu)勢(shì):

  • 你可以使用完整的編程語(yǔ)言 JavaScript 功能來(lái)構(gòu)建你的視圖頁(yè)面。比如你可以使用臨時(shí)變量、JS 自帶的流程控制、以及直接引用當(dāng)前 JS 作用域中的值等等。

  • 開(kāi)發(fā)工具對(duì) JSX 的支持相比于現(xiàn)有可用的其他 Vue 模板還是比較先進(jìn)的 (比如,linting、類型檢查、編輯器的自動(dòng)完成)。

事實(shí)上 Vue 也提供了渲染函數(shù),甚至支持 JSX。然而,我們默認(rèn)推薦的還是模板。任何合乎規(guī)范的 HTML 都是合法的 Vue 模板,這也帶來(lái)了一些特有的優(yōu)勢(shì):

  • 對(duì)于很多習(xí)慣了 HTML 的開(kāi)發(fā)者來(lái)說(shuō),模板比起 JSX 讀寫(xiě)起來(lái)更自然。這里當(dāng)然有主觀偏好的成分,但如果這種區(qū)別會(huì)導(dǎo)致開(kāi)發(fā)效率的提升,那么它就有客觀的價(jià)值存在。

  • 基于 HTML 的模板使得將已有的應(yīng)用逐步遷移到 Vue 更為容易。

  • 這也使得設(shè)計(jì)師和新人開(kāi)發(fā)者更容易理解和參與到項(xiàng)目中。

  • 你甚至可以使用其他模板預(yù)處理器,比如 Pug 來(lái)書(shū)寫(xiě) Vue 的模板。

有些開(kāi)發(fā)者認(rèn)為模板意味著需要學(xué)習(xí)額外的 DSL (Domain-Specific Language 領(lǐng)域特定語(yǔ)言) 才能進(jìn)行開(kāi)發(fā)——我們認(rèn)為這種區(qū)別是比較膚淺的。首先,JSX 并不是沒(méi)有學(xué)習(xí)成本的——它是基于 JS 之上的一套額外語(yǔ)法。同時(shí),正如同熟悉 JS 的人學(xué)習(xí) JSX 會(huì)很容易一樣,熟悉 HTML 的人學(xué)習(xí) Vue 的模板語(yǔ)法也是很容易的。最后,DSL 的存在使得我們可以讓開(kāi)發(fā)者用更少的代碼做更多的事,比如 v-on 的各種修飾符,在 JSX 中實(shí)現(xiàn)對(duì)應(yīng)的功能會(huì)需要多得多的代碼。

更抽象一點(diǎn)來(lái)看,我們可以把組件區(qū)分為兩類:一類是偏視圖表現(xiàn)的 (presentational),一類則是偏邏輯的 (logical)。我們推薦在前者中使用模板,在后者中使用 JSX 或渲染函數(shù)。這兩類組件的比例會(huì)根據(jù)應(yīng)用類型的不同有所變化,但整體來(lái)說(shuō)我們發(fā)現(xiàn)表現(xiàn)類的組件遠(yuǎn)遠(yuǎn)多于邏輯類組件。

組件作用域內(nèi)的 CSS

除非你把組件分布在多個(gè)文件上 (例如 CSS Modules),CSS 作用域在 React 中是通過(guò) CSS-in-JS 的方案實(shí)現(xiàn)的 (比如 styled-components、glamorousemotion)。這引入了一個(gè)新的面向組件的樣式范例,它和普通的 CSS 撰寫(xiě)過(guò)程是有區(qū)別的。另外,雖然在構(gòu)建時(shí)將 CSS 提取到一個(gè)單獨(dú)的樣式表是支持的,但 bundle 里通常還是需要一個(gè)運(yùn)行時(shí)程序來(lái)讓這些樣式生效。當(dāng)你能夠利用 JavaScript 靈活處理樣式的同時(shí),也需要權(quán)衡 bundle 的尺寸和運(yùn)行時(shí)的開(kāi)銷。

如果你是一個(gè) CSS-in-JS 的愛(ài)好者,許多主流的 CSS-in-JS 庫(kù)也都支持 Vue (比如 styled-components-vuevue-emotion)。這里 React 和 Vue 主要的區(qū)別是,Vue 設(shè)置樣式的默認(rèn)方法是單文件組件里類似 style 的標(biāo)簽。

單文件組件讓你可以在同一個(gè)文件里完全控制 CSS,將其作為組件代碼的一部分。

<style scoped>
  @media (min-width: 250px) {
    .list-container:hover {
      background: orange;
    }
  }
</style>

這個(gè)可選 scoped 屬性會(huì)自動(dòng)添加一個(gè)唯一的屬性 (比如 data-v-21e5b78) 為組件內(nèi) CSS 指定作用域,編譯的時(shí)候 .list-container:hover 會(huì)被編譯成類似 .list-container[data-v-21e5b78]:hover

最后,Vue 的單文件組件里的樣式設(shè)置是非常靈活的。通過(guò) vue-loader,你可以使用任意預(yù)處理器、后處理器,甚至深度集成 CSS Modules——全部都在 <style> 標(biāo)簽內(nèi)。

規(guī)模

向上擴(kuò)展

Vue 和 React 都提供了強(qiáng)大的路由來(lái)應(yīng)對(duì)大型應(yīng)用。React 社區(qū)在狀態(tài)管理方面非常有創(chuàng)新精神 (比如 Flux、Redux),而這些狀態(tài)管理模式甚至 Redux 本身也可以非常容易的集成在 Vue 應(yīng)用中。實(shí)際上,Vue 更進(jìn)一步地采用了這種模式 (Vuex),更加深入集成 Vue 的狀態(tài)管理解決方案 Vuex 相信能為你帶來(lái)更好的開(kāi)發(fā)體驗(yàn)。

兩者另一個(gè)重要差異是,Vue 的路由庫(kù)和狀態(tài)管理庫(kù)都是由官方維護(hù)支持且與核心庫(kù)同步更新的。React 則是選擇把這些問(wèn)題交給社區(qū)維護(hù),因此創(chuàng)建了一個(gè)更分散的生態(tài)系統(tǒng)。但相對(duì)的,React 的生態(tài)系統(tǒng)相比 Vue 更加繁榮。

最后,Vue 提供了 CLI 腳手架,能讓你通過(guò)交互式的腳手架引導(dǎo)非常容易地構(gòu)建項(xiàng)目。你甚至可以使用它快速開(kāi)發(fā)組件的原型。React 在這方面也提供了 create-react-app,但是現(xiàn)在還存在一些局限性:

  • 它不允許在項(xiàng)目生成時(shí)進(jìn)行任何配置,而 Vue CLI 運(yùn)行于可升級(jí)的運(yùn)行時(shí)依賴之上,該運(yùn)行時(shí)可以通過(guò)插件進(jìn)行擴(kuò)展。
  • 它只提供一個(gè)構(gòu)建單頁(yè)面應(yīng)用的默認(rèn)選項(xiàng),而 Vue 提供了各種用途的模板。
  • 它不能用用戶自建的預(yù)設(shè)配置構(gòu)建項(xiàng)目,這對(duì)企業(yè)環(huán)境下預(yù)先建立約定是特別有用的。

而要注意的是這些限制是故意設(shè)計(jì)的,這有它的優(yōu)勢(shì)。例如,如果你的項(xiàng)目需求非常簡(jiǎn)單,你就不需要自定義生成過(guò)程。你能把它作為一個(gè)依賴來(lái)更新。如果閱讀更多關(guān)于不同的設(shè)計(jì)理念。

向下擴(kuò)展

React 學(xué)習(xí)曲線陡峭,在你開(kāi)始學(xué) React 前,你需要知道 JSX 和 ES2015,因?yàn)樵S多示例用的是這些語(yǔ)法。你需要學(xué)習(xí)構(gòu)建系統(tǒng),雖然你在技術(shù)上可以用 Babel 來(lái)實(shí)時(shí)編譯代碼,但是這并不推薦用于生產(chǎn)環(huán)境。

就像 Vue 向上擴(kuò)展好比 React 一樣,Vue 向下擴(kuò)展后就類似于 jQuery。你只要把如下標(biāo)簽放到頁(yè)面就可以運(yùn)行:

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

然后你就可以編寫(xiě) Vue 代碼并應(yīng)用到生產(chǎn)中,你只要用 min 版 Vue 文件替換掉就不用擔(dān)心其他的性能問(wèn)題。

由于起步階段不需學(xué) JSX,ES2015 以及構(gòu)建系統(tǒng),所以開(kāi)發(fā)者只需不到一天的時(shí)間閱讀指南就可以建立簡(jiǎn)單的應(yīng)用程序。

原生渲染

React Native 能使你用相同的組件模型編寫(xiě)有本地渲染能力的 APP (iOS 和 Android)。能同時(shí)跨多平臺(tái)開(kāi)發(fā),對(duì)開(kāi)發(fā)者是非常棒的。相應(yīng)地,Vue 和 Weex 會(huì)進(jìn)行官方合作,Weex 是阿里巴巴發(fā)起的跨平臺(tái)用戶界面開(kāi)發(fā)框架,同時(shí)也正在 Apache 基金會(huì)進(jìn)行項(xiàng)目孵化,Weex 允許你使用 Vue 語(yǔ)法開(kāi)發(fā)不僅僅可以運(yùn)行在瀏覽器端,還能被用于開(kāi)發(fā) iOS 和 Android 上的原生應(yīng)用的組件。

在現(xiàn)在,Weex 還在積極發(fā)展,成熟度也不能和 React Native 相抗衡。但是,Weex 的發(fā)展是由世界上最大的電子商務(wù)企業(yè)的需求在驅(qū)動(dòng),Vue 團(tuán)隊(duì)也會(huì)和 Weex 團(tuán)隊(duì)積極合作確保為開(kāi)發(fā)者帶來(lái)良好的開(kāi)發(fā)體驗(yàn)。

另一個(gè)選擇是 NativeScript-Vue,一個(gè)用 Vue.js 構(gòu)建完全原生應(yīng)用的 NativeScript 插件。

MobX

Mobx 在 React 社區(qū)很流行,實(shí)際上在 Vue 也采用了幾乎相同的反應(yīng)系統(tǒng)。在有限程度上,React + Mobx 也可以被認(rèn)為是更繁瑣的 Vue,所以如果你習(xí)慣組合使用它們,那么選擇 Vue 會(huì)更合理。

Preact 和其它類 React 庫(kù)

類 React 的庫(kù)們往往盡可能地與 React 共享 API 和生態(tài)。因此上述比較對(duì)它們來(lái)說(shuō)也同樣適用。它們和 React 的不同往往在于更小的生態(tài)。因?yàn)檫@些庫(kù)無(wú)法 100% 兼容 React 生態(tài)中的全部,部分工具和輔助庫(kù)也可能無(wú)法使用?;蛘呒词箍瓷先ツ芄ぷ?,但也有可能隨時(shí)發(fā)生不兼容,除非你用的這個(gè)類 React 庫(kù)官方與 React 保持嚴(yán)格一致。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容