放兩張圖鎮壓小妖怪css
本文先講共同之處,html
再分析區別vue
大綱在此:node
共同點:react
a、都使用虛擬domwebpack
b、提供了響應式和組件化的視圖組件web
c、注意力集中保持在覈心庫,而將其餘功能如路由和全局狀態管理交給相關的庫。ajax
區別:算法
a、優化vue-router
b、HTML&CSS
c、構建工具
d、數據綁定
e、狀態管理
f、路由
g、渲染性能
h、數據更新
i、開發模式及規模
j、使用場景
k、服務器端渲染(SSR)
l、擴展(高階組件和mixin)
一、都使用虛擬DOM
vue:Vue在2.0版本引入了vdom。其vdom是基於 snabbdom 庫所作的修改。snabbdom是一個開源的vdom庫。snabbdom的主要做用就是將傳入的JS模擬的DOM結構轉換成虛擬的DOM節點。先經過其中的 h函數 將JS模擬的DOM結構轉換成虛擬DOM以後,再經過其中的 patch函數 將虛擬DOM轉換成真實的DOM渲染到頁面中。爲了保證頁面的最小化渲染,snabbdom引入了 Diff算法 ,經過Diff算法找出先後兩個虛擬DOM之間的差別,只更新改變了的DOM節點,而不從新渲染爲改變的DOM節點。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <p id="container"></p> <button id="btn-change">change</button> <!-- 引入snabbdom庫,先沒必要糾結爲何這樣引入,以及每一個文件的做用。 --> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-class.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-props.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-style.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-eventlisteners.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/h.js"></script> <script> //定義patch函數 var patch = snabbdom.init([ snabbdom_class, snabbdom_props, snabbdom_style, snabbdom_eventlisteners ]) //定義h函數 var h = snabbdom.h; //生成一個vnode var vnode = h('ul#list',{},[ h('li.item',{},['Item 1']), h('li.item',{},['Item 2']), ]) //console.log(vnode); //獲取container var container = document.getElementById('container'); patch(container,vnode);//初次渲染 var btn = document.getElementById('btn-change'); btn.onclick = function() { var newVnode = h('ul#list',{},[ h('li.item',{},['Item 1']), h('li.item',{},['Item B']), h('li.item',{},['Item 3']), ]) patch(vnode,newVnode);//再次渲染 vnode = newVnode;//將修改後的newVnode賦值給vnode } </script> </body> </html>
vue中的模板解析和渲染的核心就是:經過相似snabbdom的h()和patch()的函數,先將模板解析成vnode,若是是初次渲染,則經過patch(container,vnode)將vnode渲染至頁面,若是是二次渲染,則經過patch(vnode,newVnode),先經過Diff算法比較原vnode和newVnode的差別,以最小的代價從新渲染頁面。
react:react定義的一種相似於XML的JS擴展語法:XML+JS。
做用:用來建立react虛擬DOM(元素)對象。
//使用虛擬DOM import React from 'react' import ReactDOM from 'react-dom' import App from './App' import { BrowserRouter } from 'react-router-dom' import { Provider } from 'react-redux' import 'styles/reset.css' import 'styles/animate.css' import store from './store' ReactDOM.render( <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider>, document.getElementById('root') )
二、都提供了響應式和組件化的視圖組件
三、都把注意力集中保持在覈心庫,而將其餘功能如路由和全局狀態管理交給相關的庫。(vue-router、vuex、react-router、redux等等)
四、優化
react:
在 React 應用中,當某個組件的狀態發生變化時,它會以該組件爲根,從新渲染整個組件子樹。
如要避免沒必要要的子組件的重渲染,
你須要在全部可能的地方使用 PureComponent
,
或是手動實現 shouldComponentUpdate
方法。
react優化方法:
a、shouldComponentUpdate
b、immutable
能夠看看:http://www.javashuo.com/article/p-umzowdst-dr.html
c、react-immutable-render-mixin,實現裝飾器簡化不少寫法
d、無狀態組件
e、高階組件
vue:
在 Vue 應用中,組件的依賴是在渲染過程當中自動追蹤的,
因此係統能精確知曉哪一個組件確實須要被重渲染。
你能夠理解爲每個組件都已經自動得到了 shouldComponentUpdate
,而且沒有上述的子樹問題限制。
Vue 的這個特色使得開發者再也不須要考慮此類優化,從而可以更好地專一於應用自己。
五、HTML&CSS
react:
在 React 中,一切都是 JavaScript。
在 React 中,全部的組件的渲染功能都依靠 JSX。
JSX 是使用 XML 語法編寫 JavaScript 的一種語法糖。
import React, { Component } from 'react' import { SearchContainer, SearchContent } from './styledComponent.js' import search from 'images/search.png' class Search extends Component { render () { return ( <SearchContainer> <SearchContent { ...this.props }> <img src={search} alt=""/> <span>想吃什麼搜這裏,川菜</span> </SearchContent> </SearchContainer> ) } } export default Search
vue:
vue是把html,css,js組合到一塊兒,用各自的處理方式
Vue 設置樣式的默認方法是單文件組件裏相似 style
的標籤。
<template> <div class="m-movie"> <div class="white-bg topbar-bg"> <div class="city-entry"> <router-link tag="span" to="/cities" class="city-name">北京</router-link> </div> <div class="switch-hot"> <router-link tag="div" to="/home/movies/intheater" active-class="active" class="hot-item">正在熱映</router-link> <router-link tag="div" to="/home/movies/coming" active-class="active" class="hot-item">即將上映</router-link> </div> </div> <transition :name="transitionName"> <router-view class="movies-outlet"></router-view> </transition> </div> </template> <script> export default { data () { return { transitionName: '' } }, watch: { $route (to, from) { if ( to.meta > from.meta ) { this.transitionName = 'slide-left' } else { this.transitionName = 'slide-right' } } } } </script> <style lang="stylus" scoped> @import '~styles/border.styl' @import '~styles/variables.styl' .slide-right-enter-active, .slide-right-leave-active, .slide-left-enter-active, .slide-left-leave-active { transition: all 1s; } .slide-right-enter { opacity: 0; transform: translate3d(-100%, 0, 0); } .slide-right-leave-to { opacity: 0; transform: translate3d(100%, 0, 0); } .slide-left-enter { opacity: 0; transform: translate3d(100%, 0, 0); } .slide-left-leave-to { opacity: 0; transform: translate3d(-100%, 0, 0); } </style>
關於.vue文件怎麼運行的能夠看:
http://www.javashuo.com/article/p-cpdupjwu-en.html
六、 構建工具
react:
構建:create-react-app 快速腳手架
creat-react-app優勢 無需配置:官方的配置堪稱完美,幾乎不用你再配置任何東西,就能夠上手開發項目。 高集成性:集成了對React,JSX,ES6和Flow的支持。 自帶服務:集成了開發服務器,你能夠實現開發預覽一體化。 熱更新:保存自動更新,讓你的開發更簡單。 全兼容性:自動處理CSS的兼容問題,無需添加-webkit前綴。 自動發佈:集成好了發佈成品功能,編譯後直接發佈,而且包含了sourcemaps功能。
npm install -g create-react-app
create-react-app my-app(本身的項目名稱)
cd my-app
npm start
vue:
構建:vue-cli腳手架
yarn global add @vue/cli (vue/cli是webpack的二次開發)
七、數據綁定
vue:vue是雙向綁定, Vue.js 最核心的功能有兩個,一是響應式的數據綁定系統,二是組件系統。所謂雙向綁定,指的是vue實例中的data與其渲染的DOM元素的內容保持一致,不管誰被改變,另外一方會相應的更新爲相同的數據。這是經過設置屬性訪問器實現的。
Vue 的依賴追蹤是【原理上不支持雙向綁定,v-model 只是經過監聽 DOM 事件實現的語法糖】
vue的依賴追蹤是經過 Object.defineProperty 把data對象的屬性所有轉爲 getter/setter來實現的;當改變數據的某個屬性值時,會觸發set函數,獲取該屬性值的時候會觸發get函數,經過這個特性來實現改變數據時改變視圖;也就是說只有當數據改變時纔會觸發視圖的改變,反過來在操做視圖時,只能經過DOM事件來改變數據,再由此來改變視圖,以此來實現雙向綁定
雙向綁定是在同一個組件內,將數據和視圖綁定起來,和父子組件之間的通訊並沒有什麼關聯;
組件之間的通訊採用單向數據流是爲了組件間更好的解耦,在開發中可能有多個子組件依賴於父組件的某個數據,假如子組件能夠修改父組件數據的話,一個子組件變化會引起全部依賴這個數據的子組件發生變化,因此vue不推薦子組件修改父組件的數據,直接修改props會拋出警告
思想是響應式的,也就是基因而數據可變的,經過對每個屬性創建Watcher來監聽, 當屬性變化的時候,響應式的更新對應的虛擬dom
react:react是單向數據流;react中經過將state(Model層)與View層數據進行雙向綁定達數據的實時更新變化,具體來講就是在View層直接寫JS代碼Model層中的數據拿過來渲染,一旦像表單操做、觸發事件、ajax請求等觸發數據變化,則進行雙同步。推崇結合immutable來實現數據不可變。 能夠看看:http://www.javashuo.com/article/p-umzowdst-dr.html。react在setState以後會從新走渲染的流程,若是shouldComponentUpdate返回的是true,就繼續渲染, 若是返回了false,就不會從新渲染,PureComponent就是重寫了shouldComponentUpdate, 而後在裏面做了props和state的淺層對比;
八、狀態管理
react:redux
能夠看看:http://www.javashuo.com/article/p-xiimfjzp-y.html
vue:vuex
能夠看看:http://www.javashuo.com/article/p-kejnimiv-ge.html
九、路由
能夠直接看這個,很詳細react router @4 和 vue路由 詳解(全):http://www.javashuo.com/article/p-rfhkumuv-be.html
十、渲染性能
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() 的方法來將其渲染到頁面上,頁面上就會顯示該元素。
vue:
Vue 經過創建一個虛擬 DOM 對真實 DOM 發生的變化保持追蹤。
vue渲染的過程以下:
new Vue,執行初始化
掛載$mount方法,經過自定義Render方法、template、el等生成Render函數
經過Watcher監聽數據的變化
當數據發生變化時,Render函數執行生成VNode對象
經過patch方法,對比新舊VNode對象,經過DOM Diff算法,添加、修改、刪除真正的DOM元素
十一、數據更新
react:
React 元素都是immutable 不可變的。當元素被建立以後,你是沒法改變其內容或屬性的。一個元素就好像是動畫裏的一幀,它表明應用界面在某一時間點的樣子。
根據咱們現階段瞭解的有關 React 知識,更新界面的惟一辦法是建立一個新的元素,而後將它傳入 ReactDOM.render() 方法
vue:
數據直接修改,響應式。
十二、開發模式及規模
react:
React自己,是嚴格的view層,MVC模式
vue:
1三、使用場景
react:
a、構建一個大型應用項目
同時用Vue和React實現的簡單應用程序,可能會讓一個開發者潛意識中更加傾向於Vue。這是由於基於模板的應用程序第一眼看上去更加好理解,並且能很快跑起來。
可是這些好處引入的技術債會阻礙應用擴展到更大的規模。
模板容易出現很難注意到的運行時錯誤,同時也很難去測試,重構和分解。
相比之下,Javascript模板能夠組織成具備很好的分解性和幹(DRY)代碼的組件,幹代碼的可重用性和可測試性更好。
Vue也有組件系統和渲染函數,可是React的渲染系統可配置性更強,還有諸如淺(shallow)渲染的特性,和React的測試工具結合起來使用,使代碼的可測試性和可維護性更好。
與此同時,React的immutable應用狀態可能寫起來不夠簡潔,但它在大型應用中意義非凡,由於透明度和可測試性在大型項目中變得相當重要。
b、同時適用於Web端和原生APP
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同樣強大。
vue:
a、期待模板搭建應用
b、期待應用盡量的小和快
當應用程序的狀態改變時,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的兩倍大。
雙倍的體積並不能帶來雙倍的功能。
1四、服務器端渲染(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( 客戶端 )把剩下一部分渲染完成( 內容小,渲染快 )
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時須要有預見性,考慮如下方面。
選取最優的渲染函數。
如何支持組件的異步狀態。
如何將應用的初始化狀態傳遞到客戶端。
哪些生命週期函數能夠用於服務端的渲染。
如何爲應用提供同構路由支持。
單例、實例以及上下文的用法。
vue:
Vue.js 是構建客戶端應用程序的框架。默認狀況下,能夠在瀏覽器中輸出 Vue 組件,進行生成 DOM 和操做 DOM。然而,也能夠將同一個組件渲染爲服務器端的 HTML 字符串,將它們直接發送到瀏覽器,最後將靜態標記」混合」爲客戶端上徹底交互的應用程序。
服務器渲染的 Vue.js 應用程序也能夠被認爲是」同構」或」通用」,由於應用程序的大部分代碼均可以在服務器和客戶端上運行。
服務器端渲染優點
- 更好的 SEO,因爲搜索引擎爬蟲抓取工具能夠直接查看徹底渲染的頁面。
- 更快的內容到達時間(time-to-content),特別是對於緩慢的網絡狀況或運行緩慢的設備。無需等待全部的 JavaScript 都完成下載並執行,才顯示服務器渲染的標記,因此你的用戶將會更快速地看到完整渲染的頁面。一般能夠產生更好的用戶體驗,而且對於那些「內容到達時間(time-to-content)與轉化率直接相關」的應用程序而言,服務器端渲染(SSR)相當重要。
1五、擴展(高階組件和mixin)
react能夠經過高階組件(Higher Order Components--HOC)來擴展,而vue須要經過mixins來擴展
React剛開始也有mixin的寫法,經過React.createClass的api,不過如今不多用了。
Vue也不是不能實現高階組件,只是特別麻煩,由於Vue對與組件的option作了各類處理, 想實現高階組件就要知道每個option是怎麼處理的,而後正確的設置。
mixin小介紹:
vue中提供了一種混合機制--mixins,用來更高效的實現組件內容的複用。最開始我一度認爲這個和組件好像沒啥區別。。後來發現錯了。下面咱們來看看mixins和普通狀況下引入組件有什麼區別?
組件在引用以後至關於在父組件內開闢了一塊單獨的空間,來根據父組件props過來的值進行相應的操做,單本質上二者仍是涇渭分明,相對獨立。
而mixins則是在引入組件以後,則是將組件內部的內容如data等方法、method等屬性與父組件相應內容進行合併。至關於在引入後,父組件的各類屬性方法都被擴充了。
單純組件引用:
父組件 + 子組件 >>> 父組件 + 子組件
mixins:
父組件 + 子組件 >>> new父組件
做用:多個組件能夠共享數據和方法,在使用mixin的組件中引入後,mixin中的方法和屬性也就併入到該組件中,能夠直接使用。鉤子函數會兩個都被調用,mixin中的鉤子首先執行。
下面給你們介紹vue mixin的用法,具體介紹以下所示:
//mixin.js export default { data() { return { name: 'mixin' } }, created() { console.log('mixin...', this.name); }, mounted() {}, methods: {} }
使用:
vue文件中使用 import '@/mixin'; // 引入mixin文件 export default { mixins: [mixin] }
小結
總結一下,咱們發現,
- Vue的優點包括:
- 模板和渲染函數的彈性選擇
- 簡單的語法及項目建立
- 更快的渲染速度和更小的體積
- React的優點包括:
- 更適用於大型應用和更好的可測試性
- 同時適用於Web端和原生App
- 更大的生態圈帶來的更多支持和工具
- 而實際上,React和Vue都是很是優秀的框架,它們之間的類似之處多過不一樣之處,而且它們大部分最棒的功能是相通的:
- 利用虛擬DOM實現快速渲染
- 輕量級
- 響應式和組件化
- 服務器端渲染
- 易於集成路由工具,打包工具以及狀態管理工具
- 優秀的支持和社區
參考1:https://blog.csdn.net/CystalVon/article/details/78428036 參考2:https://cn.vuejs.org/v2/guide/comparison.html 參考3:https://www.cnblogs.com/suihang/p/10098860.html參考4:https://www.jb51.net/article/138757.htm