vue、React Nactive的區別(轉載)

Vue與React的對比

Vue.js與React.js從某些反面來講很類似,經過兩個框架的學習,有時候對一些用法會有一點思考,爲加深學習的思索,特翻閱了兩個文檔,從如下各方面進行了對比,加深了對這兩個框架的認知。css

1.數據綁定

1.1 Vue中有關數據綁定的部分

  • vue是雙向綁定, Vue.js 最核心的功能有兩個,一是響應式的數據綁定系統,二是組件系統。所謂雙向綁定,指的是vue實例中的data與其渲染的DOM元素的內容保持一致,不管誰被改變,另外一方會相應的更新爲相同的數據。這是經過設置屬性訪問器實現的。
  • 在vue中,與數據綁定有關的有 插值表達式、指令系統、*Class和Style、事件處理器和表單空間、ajax請求和計算屬性
1.1.1插值表達式

插值和指令又稱爲模板語法 
- 數據綁定最多見的形式就是使用「Mustache」語法 (雙大括號) 的文本插值 
- Mustache 語法不能做用在 HTML 特性上,遇到這種狀況應該使用 v-bind 指令html

1.1.2 指令
  • vue中的指令很方便,指令 (Directives) 是帶有 v- 前綴的特殊屬性。指令屬性的值預期是單個 JavaScript 表達式 (v-for 是例外狀況,稍後咱們再討論)。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地做用於 DOM。前端

  • vue中的12個指令: v-bind,v-once,v-model,v-text,v-html,v-on,v-if,v-else,v-show,v-for,v-pre,v-clockvue

1.1.3 class與style綁定
  • 數據綁定的一個常見需求是操做元素的 class 列表和它的內聯樣式。由於它們都是屬性 ,咱們能夠用v-bind 處理它們:只須要計算出表達式最終的字符串。不過,字符串拼接麻煩又易錯。所以,在 v-bind 用於 class 和 style 時,Vue.js 專門加強了它。表達式的結果類型除了字符串以外,還能夠是對象或數組。
  • 對象語法 
    • 咱們能夠傳給 v-bind:class 一個對象,以動態地切換 class
  • 數組語法 
    • 咱們能夠把一個數組傳給 v-bind:class,以應用一個 class 列表:
<div v-bind:class="[activeClass, errorClass]"></div>
1.1.4 條件渲染和列表渲染
  • v-if條件渲染一組數
  • 咱們用 v-for 指令根據一組數組的選項列表進行渲染。v-for 指令須要使用 item in items 形式的特殊語法,items 是源數據數組而且 item 是數組元素迭代的別名。
1.1.5 事件處理器
  • 經過v-on給元素註冊事件
  • 使用 v-on 有幾個好處: 
    • 掃一眼 HTML 模板便能輕鬆定位在 JavaScript 代碼裏對應的方法。
    • 由於你無須在 JavaScript 裏手動綁定事件,你的 ViewModel 代碼能夠是很是純粹的邏輯,和 DOM 徹底解耦,更易於測試。
    • 當一個 ViewModel 被銷燬時,全部的事件處理器都會自動被刪除。你無須擔憂如何本身清理它們。
1.1.6 表單控件
  • v-model在表單控件元素上建立雙向數據綁定
  • 它會根據控件類型自動選取正確的方法來更新元素。
1.1.7 計算屬性
  • 在Vue中引入了計算屬性來處理模板中放入太多的邏輯會讓模板太重且難以維護的問題,這樣不但解決了上面的問題,並且也同時讓模板和業務邏輯更好的分離。
  • 簡單來講,假如data裏面有屬性a=1,而後你須要一個變量跟着a變化,例如b=a+1,那麼就須要用到計算屬性,Vue實例的computed屬性中,設置b爲其屬性,其表現爲一個函數,返回值是b的值。
1.1.8 ajax數據請求
  • vue2.0中數據請求推薦使用axios
注: 關於vue的數據雙向綁定和單向數據流
  • Vue 的依賴追蹤是【原理上不支持雙向綁定,v-model 只是經過監聽 DOM 事件實現的語法糖】react

  • vue的依賴追蹤是經過 Object.defineProperty 把data對象的屬性所有轉爲 getter/setter來實現的;當改變數據的某個屬性值時,會觸發set函數,獲取該屬性值的時候會觸發get函數,經過這個特性來實現改變數據時改變視圖;也就是說只有當數據改變時纔會觸發視圖的改變,反過來在操做視圖時,只能經過DOM事件來改變數據,再由此來改變視圖,以此來實現雙向綁定ios

  • 雙向綁定是在同一個組件內,將數據和視圖綁定起來,和父子組件之間的通訊並沒有什麼關聯;
  • 組件之間的通訊採用單向數據流是爲了組件間更好的解耦,在開發中可能有多個子組件依賴於父組件的某個數據,假如子組件能夠修改父組件數據的話,一個子組件變化會引起全部依賴這個數據的子組件發生變化,因此vue不推薦子組件修改父組件的數據,直接修改props會拋出警告

1.2 react沒有數據雙向綁定

  • react是單向數據流
  • react中經過將state(Model層)與View層數據進行雙向綁定達數據的實時更新變化,具體來講就是在View層直接寫JS代碼Model層中的數據拿過來渲染,一旦像表單操做、觸發事件、ajax請求等觸發數據變化,則進行雙同步
1.2.1事件處理
  • React 元素的事件處理和 DOM元素的很類似。可是有一點語法上的不一樣:git

    • React事件綁定屬性的命名採用駝峯式寫法,而不是小寫。
    • 若是採用 JSX 的語法你須要傳入一個函數做爲事件處理函數,而不是一個字符串(DOM元素的寫法)
    • 在 React 中另外一個不一樣是你不能使用返回 false 的方式阻止默認行爲。你必須明確的使用 preventDefault。
    • 當你使用 ES6 class 語法來定義一個組件的時候,事件處理器會成爲類的一個方法。通常須要顯式的綁定this,例如github

      this.handleClick = this.handleClick.bind(this);web

    • 你必須謹慎對待 JSX 回調函數中的 this,類的方法默認是不會綁定 this 的。若是你忘記綁定 this.handleClick 並把它傳入 onClick, 當你調用這個函數的時候 this 的值會是 undefined。
1.2.2 條件渲染
  • React 中的條件渲染和 JavaScript 中的一致,使用 JavaScript 操做符 if 或條件運算符來建立表示當前狀態的元素,而後讓 React 根據它們來更新 UI。
  • 你能夠經過用花括號包裹代碼在 JSX 中嵌入任何表達式 ,也包括 JavaScript 的邏輯與 &&,它能夠方便地條件渲染一個元素。之因此能這樣作,是由於在 JavaScript 中,true && expression 老是返回 expression,而 false && expression 老是返回 false。所以,若是條件是 true,&& 右側的元素就會被渲染,若是是 false,React 會忽略並跳過它。
  • 條件渲染的另外一種方法是使用 JavaScript 的條件運算符 condition ? true : false。
1.2.3 列表渲染
  • 你能夠經過使用{}在JSX內構建一個元素集合,使用Javascript中的map()方法循遍歷數組
  • Keys能夠在DOM中的某些元素被增長或刪除的時候幫助React識別哪些元素髮生了變化。所以你應當給數組中的每個元素賦予一個肯定的標識。一個元素的key最好是這個元素在列表中擁有的一個獨一無二的字符串。一般,咱們使用來自數據的id做爲元素的key。
1.2.4 表單操做
  • HTML表單元素與React中的其餘DOM元素有所不一樣,由於表單元素生來就保留一些內部狀態。
  • 當用戶提交表單時,HTML的默認行爲會使這個表單會跳轉到一個新頁面。在React中亦是如此。但大多數狀況下,咱們都會構造一個處理提交表單並可訪問用戶輸入表單數據的函數。實現這一點的標準方法是使用一種稱爲「受控組件」的技術。其值由React控制的輸入表單元素稱爲「受控組件」。this.setState({value: event.target.value});
  • 當你有處理多個受控的input元素時,你能夠經過給每一個元素添加一個name屬性,來讓處理函數根據 event.target.name的值來選擇作什麼。
1.2.5 狀態提高
  • 在React中,狀態分享是經過將state數據提高至離須要這些數據的組件最近的父組件來完成的。這就是所謂的狀態提高。this.props.xxx
  • 在React應用中,對應任何可變數據理應只有一個單一「數據源」。一般,狀態都是首先添加在須要渲染數據的組件中。此時,若是另外一個組件也須要這些數據,你能夠將數據提高至離它們最近的父組件中。你應該在應用中保持 自上而下的數據流,而不是嘗試在不一樣組件中同步狀態。

2.組件化以及組件數據流

2.1 react中的組件及數據流

  • React是單向數據流,數據主要從父節點傳遞到子節點(經過props)。若是頂層(父級)的某個props改變了,React會重渲染全部的子節點。
  • react中實現組件有兩種實現方式,一種是createClass方法,另外一種是經過ES2015的思想類繼承React.Component來實現
  • 在React應用中,按鈕、表單、對話框、整個屏幕的內容等,這些一般都被表示爲組件。
  • React推崇的是函數式編程和單向數據流:給定原始界面(或數據),施加一個變化,就能推導出另一個狀態(界面或者數據的更新)
  • 組件能夠將UI切分紅一些的獨立的、可複用的部件,這樣你就只需專一於構建每個單獨的部件。組件從概念上看就像是函數,它能夠接收任意的輸入值(稱之爲「props」),並返回一個須要在頁面上展現的React元素。 
    1. Props的只讀性
  • 不管是使用函數或是類來聲明一個組件,它決不能修改它本身的props。
  • 全部的React組件必須像純函數那樣使用它們的props。

props與State的區別 
- props是property的縮寫,能夠理解爲HTML標籤的attribute。不可使用this.props直接修改props,由於props是隻讀的,props是用於整個組件樹中傳遞數據和配置。在當前組件訪問props,使用this.props。 
- props是一個組件的設置參數,能夠在父控件中選擇性設置。父組件對子控件的props進行賦值,而且props的值不可改變。一個子控件自身不能改變本身的 props。 
- state:當一個組件 mounts的時候,state若是設置有默認值的會被使用,而且state可能時刻的被改變。一個子控件自身能夠管理本身的state,可是須要注意的是,沒法管理其子控件的state。因此能夠認爲,state是子控件自身私有的。 
- 每一個組件都有屬於本身的state,state和props的區別在於前者(state)只存在於組件內部,只能從當前組件調用this.setState修改state值(不能夠直接修改this.state!)。 
- props是一個父組件傳遞給子組件的數據流,能夠一直的被傳遞到子孫組件中。然而 state表明的是子組件自身的內部狀態。從語義上講,改變組件的狀態,可能會致使dom結構的改變或者從新渲染。而props是父組件傳遞的參數,因此能夠被用於初始化渲染和改變組件自身的狀態,雖然大多數時候組件的狀態是又外部事件觸發改變的。咱們須要知道的是,不管是state改變,仍是父組件傳遞的 props改變,render方法均可能會被執行。 
- 通常咱們更新子組件都是經過改變state值,更新新子組件的props值從而達到更新。ajax

2.1.1 組件之間的通訊
  1. 父子組件數通訊 
    • 父與子之間通props屬性進行傳遞
    • 子與父之間,父組件定義事件,子組件觸發父組件中的事件時,經過實參的形式來改變父組件中的數據來通訊

即: 
- * 父組件更新組件狀態 —–props—–> 子組件更新 
- * 子組件更新父組件狀態 —–須要父組件傳遞迴調函數—–> 子組件調用觸發

  1. 非父子組件之間的通訊,嵌套不深的非父子組件可使共同父組件,觸發事件函數傳形參的方式來實現 
    兄弟組件:

(1) 按照React單向數據流方式,咱們須要藉助父組件進行傳遞,經過父組件回調函數改變兄弟組件的props。 
- 其實這種實現方式與子組件更新父組件狀態的方式是大同小異的。

(2) 當組件層次很深的時候,在這裏,React官方給咱們提供了一種上下文方式,可讓子組件直接訪問祖先的數據或函數,無需從祖先組件一層層地傳遞數據到子組件中。

2.1.2 組件的生命週期
construtor() //建立組件 componentWillMount() //組件掛載以前 componentDidMount() // 組件掛載以後 componentWillReceiveProps() // 父組件發生render的時候子組件調用該函數 shouldComponentUpdate() // 組件掛載以後每次調用setState後都會調用該函數判斷是否須要從新渲染組件,默認返回true componentDidUpdate() // 更新 render() //渲染,react中的核心函數 componentWillUnmount() //組件被卸載的時候調用,通常在componentDidMount註冊的事件須要在這裏刪除

組件的生命週期

2.2 vue中的組件和數據流

2.2.1 組件化應用構建
  • 組件系統是 Vue 的另外一個重要概念,由於它是一種抽象,容許咱們使用小型、獨立和一般可複用的組件構建大型應用。
  • 在 Vue 裏,一個組件本質上是一個擁有預約義選項的一個 Vue 實例
  • 在一個大型應用中,有必要將整個應用程序劃分爲組件,以使開發可管理。
  • 組件(component)是 Vue 最強大的功能之一。組件能夠幫助你擴展基本的 HTML 元素,以封裝可重用代碼。在較高層面上,組件是 Vue 編譯器附加行爲後的自定義元素。在某些狀況下,組件也能夠是原生 HTML 元素的形式,以特定的 is 特性擴展。
  • 組件中,data必須是一個函數
  • 組件能夠擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器爲它添加特殊功能。在有些狀況下,組件也能夠是原生 HTML 元素的形式,以 is 特性擴展。
2.2.2 響應式
  • 當一個 Vue 實例被建立時,它向 Vue 的響應式系統中加入了其 data 對象中能找到的全部的屬性。當這些屬性的值發生改變時,視圖將會產生「響應」,即匹配更新爲新的值。
  • 當這些數據改變時,視圖會進行重渲染。值得注意的是只有當實例被建立時 data 中存在的屬性是響應式的。
2.2.3 組件的生命週期
  • 每一個 Vue 實例在被建立以前都要通過一系列的初始化過程。例如須要設置數據監聽、編譯模板、掛載實例到 DOM、在數據變化時更新 DOM 等。同時在這個過程當中也會運行一些叫作生命週期鉤子的函數,給予用戶機會在一些特定的場景下添加他們本身的代碼。
  • 好比 created 鉤子能夠用來在一個實例被建立以後執行代碼,也有一些其它的鉤子,在實例生命週期的不一樣場景下調用,如 mounted、updated、destroyed。鉤子的 this 指向調用它的 Vue 實例。
  • 生命週期圖示: 
    vue生命週期
2.2.3 組件之間的通訊
  • Vue默認的是單向數據流,這是Vue直接提出來講明的,父組件默承認以向子組件傳遞數據,可是子組件向父組件傳遞數據就須要額外設置了。
  • Vue 也支持雙向綁定,默認爲單向綁定,數據從父組件單向傳給子組件。在大型應用中使用單向綁定讓數據流易於理解。
  • 父子組件之間的數據通訊是經過Prop和自定義事件實現的,而非父子組件可使用訂閱/發佈模式實現(相似於Angualr中的非父子指令之間的通訊),再複雜一點也是建議使用狀態管理(vuex)。
  • 在 Vue 中,父子組件之間的關係能夠概述爲:props 向下,events 向上。父組件經過 props 向下傳遞數據給子組件,子組件經過 events 發送消息給父組件。

1.父向子 
- 每一個組件實例都有本身的孤立隔離做用域。也就是說,不能(也不該該)直接在子組件模板中引用父組件數據。要想在子組件模板中引用父組件數據,可使用 props 將數據向下傳遞到子組件。 
- 每一個 prop 屬性,均可以控制是否從父組件的自定義屬性中接收數據。子組件須要使用 props 選項顯式聲明 props,以便它能夠從父組件接收到指望的數據。 
- 動態Props,相似於將一個普通屬性綁定到一個表達式,咱們還可使用 v-bind 將 props 屬性動態地綁定到父組件中的數據。不管父組件什麼時候更新數據,均可以將數據向下流入到子組件中

2.子向父 
- 使用自定義事件 
- 每一個 Vue 實例都接入了一個事件接口(events interface),也就是說,這些 Vue 實例能夠作到: 
- 使用 on(eventName)使on(eventName)監聽一個事件−使用emit(eventName) 觸發一個事件

3. 非父子組件通訊 
- 可使用一個空的 Vue 實例做爲一個事件總線中心(central event bus),用emitemit觸發事件,on監聽事件

2.2.4 單向數據流

單向數據流示意圖: 
單向數據流

3.狀態管理

3.1 react中的狀態管理:Flux

  • Redux 是 React 生態環境中最流行的 Flux 實現。Redux 事實上沒法感知視圖層,因此它可以輕鬆的經過一些簡單綁定和 Vue 一塊兒使用。 
    1. 建立actions 
      • 定義動做,事件觸發須要用dispatcher來調用
      • 行爲,如增長操做、刪除操做、更新操做,就是一堆函數。
    2. 建立store 
      • store中包含應用的狀態和邏輯,用來管理應用中不一樣的狀態和邏輯,至關於Model層
    3. 建立dispatcher 
      • 在dispatcher中經過register來給每一個action注對應的的store中的方法
    4. 在view層調用action中的方法 
      • 就是各種component

flux的示意圖

3.2 vue中的狀態管理vuex

  • vuex借鑑了 Flux、Redux、和 The Elm Architecture。與其餘模式不一樣的是,Vuex 是專門爲 Vue.js 設計的狀態管理庫,以利用 Vue.js 的細粒度數據響應機制來進行高效的狀態更新。這使得它可以更好地和 Vue 進行整合,同時提供簡潔的 API 和改善過的開發體驗。
  • 組件不容許直接修改屬於 store 實例的 state,而應執行 action 來分發 (dispatch) 事件通知 store 去改變,咱們最終達成了 Flux 架構。這樣約定的好處是,咱們可以記錄全部 store 中發生的 state 改變,同時實現能作到記錄變動 (mutation)、保存狀態快照、歷史回滾/時光旅行的先進的調試工具。

  • 每個 Vuex 應用的核心就是 store(倉庫)。「store」基本上就是一個容器,它包含着你的應用中大部分的狀態

  • Vuex 和單純的全局對象有如下兩點不一樣:

    1. Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。

    2. 你不能直接改變 store 中的狀態。改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。這樣使得咱們能夠方便地跟蹤每個狀態的變化,從而讓咱們可以實現一些工具幫助咱們更好地瞭解咱們的應用。

    3. State

  • Vuex 使用單一狀態樹——是的,用一個對象就包含了所有的應用層級狀態。至此它便做爲一個「惟一數據源 (SSOT)」而存在。這也意味着,每一個應用將僅僅包含一個 store 實例。單一狀態樹讓咱們可以直接地定位任一特定的狀態片斷,在調試的過程當中也能輕易地取得整個當前應用狀態的快照。這也意味着,每一個應用將僅僅包含一個 store 實例。 
    1. Getters
  • 從state中獲取狀態值,有時候咱們須要從 store 中的 state 中派生出一些狀態,例如對列表進行過濾並計數。

    1. Mutation 
      • 更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。Vuex 中的 mutation 很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數。
      • 你不能直接調用一個 mutation handler。這個選項更像是事件註冊:「當觸發一個類型爲 increment 的 mutation 時,調用此函數。」要喚醒一個 mutation handler,你須要以相應的 type 調用 store.commit 方法
    2. Action

      • Action 相似於 mutation,不一樣在於:

      • Action 提交的是 mutation,而不是直接變動狀態。

      • Action 能夠包含任意異步操做。
      • dispatch分發action
    3. Module

  • 因爲使用單一狀態樹,應用的全部狀態會集中到一個比較大的對象。當應用變得很是複雜時,store 對象就有可能變得至關臃腫。
  • Vuex 容許咱們將 store 分割成模塊(module)。每一個模塊擁有本身的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行一樣方式的分割

vuex示意圖

4.路由

  • 二者的路由很類似,都是利用了組件化思想

4.1 react中的路由

  • 在路由庫的問題上,React 選擇把問題交給社區維護,所以建立了一個更分散的生態系統。但相對的,React 的生態系統相比 Vue 更加繁榮。
  • react中,須要引入react-router庫, 
    使用時,路由器Router就是React的一個組件。
  • Router組件自己只是一個容器,真正的路由要經過Route組件定義。
  • Route組件定義了URL路徑與組件的對應關係。你能夠同時使用多個Route組件。
<Router history={hashHistory}> <Route path="/" component={App}/> <Route path="/repos" component={Repos}/> <Route path="/about" component={About}/> </Router>

- Link組件用於取代元素,生成一個連接,容許用戶點擊後跳轉到另外一個路由。它基本上就是元素的React 版本,能夠接收Router的狀態。

4.2 vue中的路由

  • Vue 的路由庫和狀態管理庫都是由官方維護支持且與核心庫同步更新的。
  • 使用 Vue.js ,咱們已經能夠經過組合組件來組成應用程序,當你要把 vue-router 添加進來,咱們須要作的是,將組件(components)映射到路由(routes),而後告訴 vue-router 在哪裏渲染它們。

    1. HTML中:
<div id="app"> <h1>Hello App!</h1> <p> <!-- 使用 router-link 組件來導航. --> <!-- 經過傳入 `to` 屬性指定連接. --> <!-- <router-link> 默認會被渲染成一個 `<a>` 標籤 --> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> </p> <!-- 路由出口 --> <!-- 路由匹配到的組件將渲染在這裏 --> <router-view></router-view> </div>

5. 渲染性能對比

  • 在操做界面時,要儘可能減小對DOM的操做,Vue 和 React 都使用虛擬DOM來實現,而且二者工做同樣好。
  • 儘可能減小除DOM操做之外的其餘操做。(vue和react的不一樣)

5.1 react視圖渲染

  • React 的渲染創建在 Virtual DOM 上——一種在內存中描述 DOM 樹狀態的數據結構。當狀態發生變化時,React 從新渲染 Virtual DOM,比較計算以後給真實 DOM 打補丁。

  • Virtual DOM 提供了函數式的方法描述視圖,它不使用數據觀察機制,每次更新都會從新渲染整個應用,所以從定義上保證了視圖與數據的同步。它也開闢了 JavaScript 同構應用的可能性。

  • 在超大量數據的首屏渲染速度上,React 有必定優點,由於 Vue 的渲染機制啓動時候要作的工做比較多,並且 React 支持服務端渲染。

  • 元素是構成 React 應用的最小單位。元素用來描述你在屏幕上看到的內容,與瀏覽器的 DOM 元素不一樣,React 當中的元素事實上是普通的對象,React DOM 能夠確保 瀏覽器 DOM 的數據內容與 React 元素保持一致。

  • 咱們用React 開發應用時通常只會定義一個根節點。但若是你是在一個已有的項目當中引入 React 的話,你可能會須要在不一樣的部分單獨定義 React 根節點。咱們將 元素傳入一個名爲 ReactDOM.render() 的方法來將其渲染到頁面上,頁面上就會顯示該元素。

組件渲染 
- 當React遇到的元素是用戶自定義的組件,它會將JSX屬性做爲單個對象傳遞給該組件,這個對象稱之爲「props」。

5.2 vue視圖渲染

  • Vue 經過創建一個虛擬 DOM 對真實 DOM 發生的變化保持追蹤。

  • vue渲染的過程以下:

    • new Vue,執行初始化
    • 掛載$mount方法,經過自定義Render方法、template、el等生成Render函數
    • 經過Watcher監聽數據的變化
    • 當數據發生變化時,Render函數執行生成VNode對象
    • 經過patch方法,對比新舊VNode對象,經過DOM Diff算法,添加、修改、刪除真正的DOM元素

6. 數據更新

6.1 react數據更新

  • React 元素都是immutable 不可變的。當元素被建立以後,你是沒法改變其內容或屬性的。一個元素就好像是動畫裏的一幀,它表明應用界面在某一時間點的樣子。
  • 根據咱們現階段瞭解的有關 React 知識,更新界面的惟一辦法是建立一個新的元素,而後將它傳入 ReactDOM.render() 方法

6.2 vue數據更新

7. 開發模式及規模

7.1 react

7.1.1 開發模式
  • React自己,是嚴格的view層,MVC模式
7.1.2 規模
  • Vue 提供了Vue-cli 腳手架,能讓你很是容易地構建項目,包含了 Webpack,Browserify,甚至 no build system。

7.2 vue

7.2.1 開發模式
  • Vue是MVVM模式的一種方式實現
  • 雖然沒有徹底遵循 MVVM 模型,Vue 的設計無疑受到了它的啓發。所以在文檔中常常會使用 vm (ViewModel 的簡稱) 這個變量名錶示 Vue 實例。
7.2.2 腳手架
  • React 提供了create-react-app,可是如今還存在一些侷限性: 
    • 它不容許在項目生成時進行任何配置,而 Vue 支持 Yeoman-like 定製。
    • 它只提供一個構建單頁面應用的單一模板,而 Vue 提供了各類用途的模板。
    • 它不能用用戶自建的模板構建項目,而自建模板對企業環境下預先創建協議是特別有用的。

8. HTML&&CSS

  • 在 React 中,一切都是 JavaScript。不只僅是 HTML 能夠用 JSX 來表達,如今的潮流也愈來愈多地將 CSS 也歸入到 JavaScript 中來處理。這類方案有其優勢,但也存在一些不是每一個開發者都能接受的取捨。

- Vue 的總體思想是擁抱經典的 Web 技術,並在其上進行擴展。

8.1 react

8.1.1 JSX
  • 在 React 中,全部的組件的渲染功能都依靠 JSX。JSX 是使用 XML 語法編寫 JavaScript 的一種語法糖。
  • JSX, 一種 JavaScript 的語法擴展。 咱們推薦在 React 中使用 JSX 來描述用戶界面。JSX 乍看起來可能比較像是模版語言,但事實上它徹底是在 JavaScript 內部實現的。

  • JSX 用來聲明 React 當中的元素。

  • JSX自己也是一種表達式,在編譯以後呢,JSX 其實會被轉化爲普通的 JavaScript 對象。這也就意味着,你其實能夠在 if 或者 for 語句裏使用 JSX,將它賦值給變量,看成參數傳入,做爲返回值均可以
  • JSX 說是手寫的渲染函數有下面這些優點: 
    • 你可使用完整的編程語言 JavaScript 功能來構建你的視圖頁面。好比你可使用臨時變量、JS 自帶的流程控制、以及直接引用當前 JS 做用域中的值等等。
    • 開發工具對 JSX 的支持相比於現有可用的其餘 Vue 模板仍是比較先進的 (好比,linting、類型檢查、編輯器的自動完成)。
8.1.2 組件做用域內的CSS
  • 除非你把組件分佈在多個文件上 (例如 CSS Modules),CSS 做用域在 React 中是經過 CSS-in-JS 的方案實現的 (好比 styled-components、glamorous 和 emotion)。這引入了一個新的面向組件的樣式範例,它和普通的 CSS 撰寫過程是有區別的。另外,雖然在構建時將 CSS 提取到一個單獨的樣式表是支持的,但 bundle 裏一般仍是須要一個運行時程序來讓這些樣式生效。當你可以利用 JavaScript 靈活處理樣式的同時,也須要權衡 bundle 的尺寸和運行時的開銷。

8.2 vue

8.2.1 Templates模板語法
  • 事實上 Vue 也提供了渲染函數,甚至支持 JSX。然而,咱們默認推薦的仍是模板。任何合乎規範的 HTML 都是合法的 Vue 模板,這也帶來了一些特有的優點: 
    • 對於不少習慣了 HTML 的開發者來講,模板比起 JSX 讀寫起來更天然。這裏固然有主觀偏好的成分,但若是這種區別會致使開發效率的提高,那麼它就有客觀的價值存在。
    • 基於 HTML 的模板使得將已有的應用逐步遷移到 Vue 更爲容易。
    • 這也使得設計師和新人開發者更容易理解和參與到項目中。
    • 你甚至可使用其餘模板預處理器,好比 Pug 來書寫 Vue 的模板。
  • Vue.js 使用了基於 HTML 的模板語法,容許開發者聲明式地將 DOM 綁定至底層 Vue 實例的數據。全部 Vue.js 的模板都是合法的 HTML ,因此能被遵循規範的瀏覽器和 HTML 解析器解析。
  • 在底層的實現上,Vue 將模板編譯成虛擬 DOM 渲染函數。結合響應系統,在應用狀態改變時,Vue 可以智能地計算出從新渲染組件的最小代價並應用到 DOM 操做上。
8.2.2 單文件組件CSS
  • Vue 設置樣式的默認方法是單文件組件裏相似 style 的標籤。 
    單文件組件讓你能夠在同一個文件裏徹底控制 CSS,將其做爲組件代碼的一部分。
  • Vue 的單文件組件裏的樣式設置是很是靈活的。經過 vue-loader,你可使用任意預處理器、後處理器,甚至深度集成 CSS Modules——所有都在

8.3 小結

  • 更抽象一點來看,咱們能夠把組件區分爲兩類:一類是偏視圖表現的 (presentational),一類則是偏邏輯的 (logical)。咱們推薦在前者中使用模板,在後者中使用 JSX 或渲染函數。這兩類組件的比例會根據應用類型的不一樣有所變化,但總體來講咱們發現表現類的組件遠遠多於邏輯類組件。

9. 使用場景

9.1 選擇react

9.1.1 期待構建一個大型應用程序——選擇React
  • 同時用Vue和React實現的簡單應用程序,可能會讓一個開發者潛意識中更加傾向於Vue。這是由於基於模板的應用程序第一眼看上去更加好理解,並且能很快跑起來。可是這些好處引入的技術債會阻礙應用擴展到更大的規模。模板容易出現很難注意到的運行時錯誤,同時也很難去測試,重構和分解。 
    相比之下,Javascript模板能夠組織成具備很好的分解性和幹(DRY)代碼的組件,幹代碼的可重用性和可測試性更好。Vue也有組件系統和渲染函數,可是React的渲染系統可配置性更強,還有諸如淺(shallow)渲染的特性,和React的測試工具結合起來使用,使代碼的可測試性和可維護性更好。 
    與此同時,React的immutable應用狀態可能寫起來不夠簡潔,但它在大型應用中意義非凡,由於透明度和可測試性在大型項目中變得相當重要。
9.1.2 期待同時適用於Web端和原生APP的框架——選擇React
  • React Native是一個使用Javascript構建移動端原生應用程序(iOS,Android)的庫。 它與React.js相同,只是不使用Web組件,而是使用原生組件。 若是你學過React.js,很快就能上手React Native,反之亦然。 
    它的意義在於,開發者只須要一套知識和工具就能開發Web應用和移動端原生應用。若是你想同時作Web端開發和移動端開發,React爲你準備了一份大禮。 
    阿里的Weex也是一個跨平臺UI項目,目前它以Vue爲靈感,使用了許多相同的語法,同時計劃在將來徹底集成Vue,然而集成的時間和細節還不清楚。由於Vue將HTML模板做爲它設計的核心部分,而且現有特性不支持自定義渲染,所以很難看出目前的Vue.js的跨平臺能力能像React和React Native同樣強大。
9.1.3 期待最大的生態系統——選擇React
  • 毫無疑問,React是目前最受歡迎的前端框架。它在NPM上每月的下載量超過了250萬次,相比之下,Vue是22.5萬次。人氣不只僅是一個膚淺的數字,這意味着更多的文章,教程和更多Stack Overflow的解答,還意味有着更多的工具和插件能夠在項目中使用,讓開發者再也不孤立無援。 
    這兩個框架都是開源的,可是React誕生於Facebook,有Facebook背書,它的開發者和Facebook都承諾會持續維護React。相比之下,Vue是獨立開發者尤雨溪的做品。尤雨溪目前在全職維護Vue,也有一些公司資助Vue,可是規模和Facebook和Google沒得比。不過請對Vue的團隊放心,它的小規模和獨立性並無成爲劣勢,Vue有着固定的發佈週期,甚至更使人稱道的是,Github上Vue只有54個open issue,3456個closed issue,做爲對比,React有多達530個open issue,3447個closed issue。

9.2 選擇vue

9.2.1 期待模板搭建應用——選擇 Vue
  • Vue應用的默認選項是把markup放在HTML文件中。數據綁定表達式採用的是和Angular類似的mustache語法,而指令(特殊的HTML屬性)用來向模板添加功能。 
    相比之下,React應用不使用模板,它要求開發者藉助JSX在JavaScript中建立DOM。
  • 對於來自標準Web開發方式的新開發者,模板更容易理解。可是一些資深開發者也喜歡模板,由於模板能夠更好的把佈局和功能分割開來,還可使用Pug之類的模板引擎。 
    可是使用模板的代價是不得不學習全部的HTML擴展語法,而渲染函數只須要會標準的HTML和JavaScript。並且比起模板,渲染函數更加容易調試和測試。固然你不該該由於這方面的緣由錯過Vue,由於在Vue2.0中提供了使用模板或者渲染函數的選項。
9.2.2 期待簡單和「能用就行」的東西——選擇 Vue
  • 一個簡單的Vue項目能夠不須要轉譯直接運行在瀏覽器中,因此使用Vue能夠像使用jQuery同樣簡單。固然這對於React來講在技術上也是可行的,可是典型的React代碼是重度依賴於JSX和諸如class之類的ES6特性的。 
    Vue的簡單在程序設計的時候體現更深,讓咱們來比較一下兩個框架是怎樣處理應用數據的(也就是state)。
  • React中是經過比較當前state和前一個state來決定什麼時候在DOM中進行重渲染以及渲染的內容,所以須要不可變(immutable)的state。 
    Vue中的數據是可變(mutated)的,因此一樣的操做看起來更加簡潔。 
    讓咱們來看看Vue中是如何進行狀態管理的。當向state添加一個新對象的時候,Vue將遍歷其中的全部屬性而且轉換爲getter,setter方法,如今Vue的響應系統開始保持對state的跟蹤了,當state中的內容發生變化的時候就會自動從新渲染DOM。使人稱道的是,Vue中改變state的狀態的操做不只更加簡潔,並且它的從新渲染系統也比React 的更快更有效率。
  • Vue的響應系統還有有些坑的,例如:它不能檢測屬性的添加和刪除和某些數組更改。這時候就要用到Vue API中的相似於React的set方法來解決。
9.2.3 期待應用盡量的小和快——選擇Vue
  • 當應用程序的狀態改變時,React和Vue都將構建一個虛擬DOM並同步到真實DOM中。 二者都有各自的方法優化這個過程。 
    Vue核心開發者提供了一個benchmark測試,能夠看出Vue的渲染系統比React的更快。測試方法是10000個項目的列表渲染100次,結果以下圖。從實用的觀點來看,這種benchmark只和邊緣狀況有關,大部分應用程序中不會常常進行這種操做,因此這不該該被視爲一個重要的比較點。可是,頁面大小是與全部項目有關的,這方面Vue再次領先,它目前的版本壓縮後只有25.6KB。React要實現一樣的功能,你須要React DOM(37.4KB)和React with Addon庫(11.4KB),共計44.8KB,幾乎是Vue的兩倍大。雙倍的體積並不能帶來雙倍的功能。

10. 服務器端渲染(SSR)

  • 客戶端渲染路線:1. 請求一個html -> 2. 服務端返回一個html -> 3. 瀏覽器下載html裏面的js/css文件 -> 4. 等待js文件下載完成 -> 5. 等待js加載並初始化完成 -> 6. js代碼終於能夠運行,由js代碼向後端請求數據( ajax/fetch ) -> 7. 等待後端數據返回 -> 8. react-dom( 客戶端 )從無到完整地,把數據渲染爲響應頁面

  • 服務端渲染路線:1. 請求一個html -> 2. 服務端請求數據( 內網請求快 ) -> 3. 服務器初始渲染(服務端性能好,較快) -> 4. 服務端返回已經有正確內容的頁面 -> 5. 客戶端請求js/css文件 -> 6. 等待js文件下載完成 -> 7. 等待js加載並初始化完成 -> 8. react-dom( 客戶端 )把剩下一部分渲染完成( 內容小,渲染快 )

10.1 react

  • React的虛擬DOM是其可被用於服務端渲染的關鍵。首先每一個ReactComponent 在虛擬DOM中完成渲染,而後React經過虛擬DOM來更新瀏覽器DOM中產生變化的那一部分,虛擬DOM做爲內存中的DOM表現,爲React在Node.js這類非瀏覽器環境下的吮吸給你提供了可能,React能夠從虛擬DoM中生成一個字符串。而不是跟新真正的DOM,這使得咱們能夠在客戶端和服務端使用同一個React Component。

  • React 提供了兩個可用於服務端渲染組件的函數:React.renderToString 和React.render-ToStaticMarkup。 在設計用於服務端渲染的ReactComponent時須要有預見性,考慮如下方面。

    • 選取最優的渲染函數。
    • 如何支持組件的異步狀態。
    • 如何將應用的初始化狀態傳遞到客戶端。
    • 哪些生命週期函數能夠用於服務端的渲染。
    • 如何爲應用提供同構路由支持。
    • 單例、實例以及上下文的用法。

10.2 vue

1. 什麼是服務器端渲染(SSR)?

  • Vue.js 是構建客戶端應用程序的框架。默認狀況下,能夠在瀏覽器中輸出 Vue 組件,進行生成 DOM 和操做 DOM。然而,也能夠將同一個組件渲染爲服務器端的 HTML 字符串,將它們直接發送到瀏覽器,最後將靜態標記」混合」爲客戶端上徹底交互的應用程序。

  • 服務器渲染的 Vue.js 應用程序也能夠被認爲是」同構」或」通用」,由於應用程序的大部分代碼均可以在服務器和客戶端上運行。

2. 服務器端渲染優點 
- 更好的 SEO,因爲搜索引擎爬蟲抓取工具能夠直接查看徹底渲染的頁面。 
- 更快的內容到達時間(time-to-content),特別是對於緩慢的網絡狀況或運行緩慢的設備。無需等待全部的 JavaScript 都完成下載並執行,才顯示服務器渲染的標記,因此你的用戶將會更快速地看到完整渲染的頁面。一般能夠產生更好的用戶體驗,而且對於那些「內容到達時間(time-to-content)與轉化率直接相關」的應用程序而言,服務器端渲染(SSR)相當重要。

11. 附: react理念

1. 把UI圖劃分出組件層級
2. 用React建立一個靜態版本
  • 傳入數據模型,渲染 UI 但沒有任何交互。最好把這些過程解耦,由於建立一個靜態版本更多須要的是碼代碼,不太須要邏輯思考,而添加交互則更多須要的是邏輯思考,不是碼代碼。
  • 在建立靜態版本的時候不要使用 state。
  • 你能夠自頂向下或者自底向上構建應用。也就是,你能夠從層級最高的組件開始構建(即 FilterableProductTable開始)或層級最低的組件開始構建(ProductRow)。在較爲簡單的例子中,一般自頂向下更容易,而在較大的項目中,自底向上會更容易而且在你構建的時候有利於編寫測試。
  • React 的單向數據流(也叫做單向綁定)保證了一切是模塊化而且是快速的。
3. 定義 UI 狀態的最小(但完整)表示
  • 想一想實例應用中的數據,讓咱們來看看每一條,找出哪個是 state。每一個數據只要考慮三個問題:

    • 它是經過 props 從父級傳來的嗎?若是是,他可能不是 state。
    • 它隨着時間推移不變嗎?若是是,它可能不是 state。
    • 你可以根據組件中任何其餘的 state 或 props 把它計算出來嗎?若是是,它不是 state。
4. 肯定你的State應該位於哪裏
  • 對你應用的每個 state:

    • 肯定每個須要這個 state 來渲染的組件。
    • 找到一個公共全部者組件(一個在層級上高於全部其餘須要這個 state 的組件的組件)
    • 這個公共全部者組件或另外一個層級更高的組件應該擁有這個 state。
    • 若是你沒有找到能夠擁有這個 state 的組件,建立一個僅用來保存狀態的組件並把它加入比這個公共全部者組件層級更高的地方。
5. 添加反向數據流

小結

總結一下,咱們發現, 
- Vue的優點包括: 
- 模板和渲染函數的彈性選擇 
- 簡單的語法及項目建立 
- 更快的渲染速度和更小的體積 
- React的優點包括: 
- 更適用於大型應用和更好的可測試性 
- 同時適用於Web端和原生App 
- 更大的生態圈帶來的更多支持和工具 
- 而實際上,React和Vue都是很是優秀的框架,它們之間的類似之處多過不一樣之處,而且它們大部分最棒的功能是相通的: 
- 利用虛擬DOM實現快速渲染 
- 輕量級 
- 響應式和組件化 
- 服務器端渲染 
- 易於集成路由工具,打包工具以及狀態管理工具 
- 優秀的支持和社區

文章參考來源:

相關文章
相關標籤/搜索