reactjs和vuejs的區別是什麼

joytoy發表於2021-09-11

reactjs和vuejs的區別:1、vue是資料雙向繫結,react不是雙向繫結;2、非父子元件實現通訊,react使共同父元件觸發事件函式傳形參的方式,vue使用訂閱/釋出模式的方式;3、react用Redux進行狀態管理,vue使用vuex。

reactjs和vuejs的區別是什麼

本教程操作環境:windows7系統、vue2.9.6&&react16版,DELL G3電腦。

Vue.js與React.js從某些反面來說很相似,透過兩個框架的學習,有時候對一些用法會有一點思考,為加深學習的思索,特翻閱了兩個文件,從以下各方面進行了對比,加深了對這兩個框架的認知。

1.資料繫結

1.1 Vue中有關資料繫結的部分

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

1.1.1插值表示式

插值和指令又稱為模板語法
- 資料繫結最常見的形式就是使用“Mustache”語法 (雙大括號) 的文字插值
- Mustache 語法不能作用在 HTML 特性上,遇到這種情況應該使用 v-bind 指令

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-clock

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 事件實現的語法糖】

  • vue的依賴追蹤是透過 Object.defineProperty 把data物件的屬性全部轉為 getter/setter來實現的;當改變資料的某個屬性值時,會觸發set函式,獲取該屬性值的時候會觸發get函式,透過這個特性來實現改變資料時改變檢視;也就是說只有當資料改變時才會觸發檢視的改變,反過來在操作檢視時,只能透過DOM事件來改變資料,再由此來改變檢視,以此來實現雙向繫結

  • 雙向繫結是在同一個元件內,將資料和檢視繫結起來,和父子元件之間的通訊並無什麼關聯;
  • 元件之間的通訊採用單向資料流是為了元件間更好的解耦,在開發中可能有多個子元件依賴於父元件的某個資料,假如子元件可以修改父元件資料的話,一個子元件變化會引發所有依賴這個資料的子元件發生變化,所以vue不推薦子元件修改父元件的資料,直接修改props會丟擲警告

1.2 react沒有資料雙向繫結

  • react是單向資料流
  • react中透過將state(Model層)與View層資料進行雙向繫結達資料的實時更新變化,具體來說就是在View層直接寫JS程式碼Model層中的資料拿過來渲染,一旦像表單操作、觸發事件、ajax請求等觸發資料變化,則進行雙同步

1.2.1事件處理

  • React 元素的事件處理和 DOM元素的很相似。但是有一點語法上的不同:

    • React事件繫結屬性的命名採用駝峰式寫法,而不是小寫。
    • 如果採用 JSX 的語法你需要傳入一個函式作為事件處理函式,而不是一個字串(DOM元素的寫法)
    • 在 React 中另一個不同是你不能使用返回 false 的方式阻止預設行為。你必須明確的使用 preventDefault。
    • 當你使用 ES6 class 語法來定義一個元件的時候,事件處理器會成為類的一個方法。一般需要顯式的繫結this,例如

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

    • 你必須謹慎對待 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值從而達到更新。

2.1.1 元件之間的通訊

1、父子元件數通訊

  • 父與子之間通props屬性進行傳遞
  • 子與父之間,父元件定義事件,子元件觸發父元件中的事件時,透過實參的形式來改變父元件中的資料來通訊

即:
- * 父元件更新元件狀態 —–props—–> 子元件更新
- * 子元件更新父元件狀態 —–需要父元件傳遞迴調函式—–> 子元件呼叫觸發

2、非父子元件之間的通訊,巢狀不深的非父子元件可以使共同父元件,觸發事件函式傳形參的方式來實現

兄弟元件:

(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)監聽一個事件−使用emit(eventName) 觸發一個事件

3. 非父子元件通訊
- 可以使用一個空的 Vue 例項作為一個事件匯流排中心(central event bus),用emit觸發事件,on監聽事件

3.狀態管理

3.1 react中的狀態管理:Flux

  • Redux 是 React 生態環境中最流行的 Flux 實現。Redux 事實上無法感知檢視層,所以它能夠輕鬆的透過一些簡單繫結和 Vue 一起使用。
    建立actions
    • 定義動作,事件觸發需要用dispatcher來呼叫
    • 行為,如增加操作、刪除操作、更新操作,就是一堆函式。
    建立store
    • store中包含應用的狀態和邏輯,用來管理應用中不同的狀態和邏輯,相當於Model層
    建立dispatcher
    • 在dispatcher中透過register來給每個action注對應的的store中的方法
    在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 例項。
  • 從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、甚至是巢狀子模組——從上至下進行同樣方式的分割

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 在哪裡渲染它們。

    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實現快速渲染
- 輕量級
- 響應式和元件化
- 伺服器端渲染
- 易於整合路由工具,打包工具以及狀態管理工具
- 優秀的支援和社群

相關推薦:《》

以上就是reactjs和vuejs的區別是什麼的詳細內容,更多請關注php中文網其它相關文章!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4650/viewspace-2827285/,如需轉載,請註明出處,否則將追究法律責任。

相關文章