vue與react詳細
一、全景圖
二、背景
1、react:專業
- react 誕生於2011年( FaxJS),
- 2013 年 7 月 3 日 v0.3.0
- 2016 年 3 月 30 日 v0.14.8
- 2016 年 4 月 9 日 v15.0.0
- 2017 年 9 月 27 日 v16.0.0,fiber正式誕生
- 2019 年 react 16.8發佈 正式支持 hooks語法。
- 2020 年 10 月 22 日 v17
解決問題:
React
用來解決什麼問題,官方網站上這樣說道: We build React to solve one problem:building large applications with data that changes over time.
2、vue:傳奇
發端於2013年的個人項目,但如今已然成為世界三大前端框架之一,在中國大陸更是前端首選。(面試官問:為什麼你學習用vue?答:因為愛國!)
- 2013年,在
Google
工作的尤雨溪,受到Angular
的啟發,從中提取自己所喜歡的部分,開發出瞭一款輕量框架,最初命名為Seed
。 - 同年12月,這粒種子發芽瞭,更名為
Vue
(因為是個視圖層庫,而 vue 是view
的法語),版本號是0.6.0。 - 2014.01.24,Vue正式對外發佈,版本號是0.8.0。
- 發佈於2014.02.25的0.9.0,有瞭自己的代號:
Animatrix
,這個名字來自動畫版的《駭客帝國》,此後,重要的版本都會有自己的代號。 - 0.12.0發佈於2015.06.13,代號
Dragon Ball
(龍珠),這一年,Vue迎來瞭大爆發,Laravel
社區(一款流行的 PHP 框架的社區)首次使用 Vue,Vue
在JS社區也打響瞭知名度。 1.0.0 Evangelion
(新世紀福音戰士)是Vue
歷史上的第一個裡程碑。同年,vue-router
(2015-08-18)、vuex(2015-11-28)、vue-cli
(2015-12-27)相繼發佈,標志著Vue
從一個視圖層庫發展為一個漸進式框架。很多前端同學也是從這個版本開始成為Vue的用戶(vue1純純的響應式)。- 2016年10月1日 2.0.0
Ghost in the Shell
(攻殼機動隊)是第二個重要的裡程碑,它吸收瞭React
的Virtual Dom
方案,還支持服務端渲染。 - 2019年2月4日 在2.6發佈之前的很長一段時間,
Vue
核心團隊都在忙著vue-cli3.0
的開發,積攢瞭不少需求,發佈瞭vue2
倒數第二個的版本(2020年發佈) - 2020年09月18日 帶著成為任何人都可以快速學習、易於接近的框架的使命
vue3
它來瞭,同年還推出瞭新時代打包工具vite(未來可能會取代webpack
)
vue群眾基礎圖 如下圖:
三、技術思想
react
整體上是函數式的思想,組件使用jsx語法,all in js
,將html
與css全都融入javaScript
,jsx語法相對來說更加靈活。
vue的整體思想仍然是擁抱經典的html
(結構)+css(表現)+js(行為)的形式,vue鼓勵開發者使用template
模板,並提供指令供開發者使用如v-if
、v-show
、v-for等指令,因此在開發vue應用的時候會有一種在寫經典web應用(結構、表現、行為分離)的感覺。
一些老生常談的 數據管理(props
、data vs state
)、組件寫法、生命周期異同這裡就不比較瞭。
1、key的異同為例
1、react
與vue在列表加key的問題上最終目的是一致的:更準確、更快地拿到oldVnode
中對應的vnode節點,提高性能。但是它們實現的算法卻有一定的差異。
1.1 react
React在渲染數組時如果子組件沒有提供key,會默認將循環的index作為key來用作第一次渲染。 源碼本質上就是暴力比較法:由於單鏈表fiber無法使用雙指針算法,所以無法對算法使用雙指針優化。總體上經歷兩輪遍歷,第一輪遍歷:處理更新的節點。第二輪遍歷:處理剩下的不屬於更新的節點。
為瞭降低算法復雜度,React的diff會預設限制:
隻對同級元素進行Diff。如果一個DOM節點在前後兩次更新中跨越瞭層級,那麼React不會嘗試復用他。
兩個不同類型的元素會產生出不同的樹。如果元素由div變為p,React
會銷毀div及其子孫節點,並新建p及其子孫節點。
先判斷key再判斷type,兩者相同則為同一節點。更新>新增/刪除
1.2 vue
vue
在diff性能方面要強於react,當我認真閱讀瞭源碼與書籍後,佩服至極, 力扣算法題–最長遞增子序列 舉個例子吧:以數組[2, 11, 6, 8, 1]為例:最終輸出的結果為[0, 2, 3],表示最強增長序列的索引分別是0,2,3;對應的值是2,6,8。換句話說,在這個數組中最長連續增長的值就是數組中的2,6,8三個元素。
那麼vue3費瞭這麼大的力氣,使用這個方法的目的是什麼呢? Vue2在DOM-Diff
過程中,優先處理特殊場景的情況,即頭頭比對,頭尾比對,尾頭比對等。
而Vue3在DOM-Diff
過程中,根據 newIndexToOldIndexMap
新老節點索引列表找到最長穩定序列,通過最長增長子序列的算法比對,找出新舊節點中不需要移動的節點,原地復用,僅對需要移動或已經patch
(新增刪除節點等操作)節點進行操作,最大限度地提升替換效率,相比於Vue2版本是質的提升!
2、diff的宏觀比較
2.1 react
在react中如果某個組件的狀態發生改變,react會把此組件以及此組件的所有後代組件重新渲染,不過重新渲染並不代表會全部丟棄上一次的渲染結果,react
還是會通過diff
去比較兩次的虛擬dom最後patch
到真實的dom上。雖然如此,如果組件樹過大,diff其實還是會有一部分的開銷。react
內部通過 fiber
優化 diff算法,外部建議開發者使用 shouldComponentUpdate pureComponent
來規避問題。
2.2 vue
vue2的響應式是Object.defineProperty實現的,並且重寫getter“setter等一系列操作實現觀察者模式,一旦數據發生變化,不會像react一樣去比較整顆組件樹,而是去更新數據狀態變化瞭的組件實例。
3、生命周期
3.1 react 生命周期
old 15.x-16
new 16+
其他:componentDidCatch
React
生命周期的命名一直都是非常語義化(小聲bb:真是又臭又長又難記)
3.2 vue生命周期
4、函數式編程
雙方都做出瞭大規模的改動,雖然源碼不同,但設計思想以及代碼簡易程度來看,確實都在進步。
4.1 react hooks
原先繁瑣的 compomentDidUpdate
生命周期 =》 useEffect
,雖然不完全相同,但在大多數場景中,從開發者層面看待,我們更多是關心props
或者state中的數據變化之後,會產生瞭什麼後果(副作用),省去瞭開發者自己比較前後值的過程。(這應該是react借鑒vue watch
)
4.2 vue3 組合式api
vue3
組合式api借鑒瞭react hooks
中的部分思想,不得不說,青出於藍而勝於藍,再加上框架自己也做出瞭很多優化工作,在性能上是react比不上的。
function() { useEffect(()=>{ // 當demo發生變化時觸發 console.log(demo) },[demo]) return ( <div>react</div> ) }
import {reactive, watchEffect} from 'vue' export default { setup() { const state = reactive({ count: 0, name: 'zs' }) watchEffect(() => { console.log(state.count) console.log(state.name) }) return { state } } }
由於初始化時源碼內部的響應式機制的緣故,新APIwatchEffect
甚至都不需要監聽是誰發生瞭變化就可以觸發副作用,因為監聽的這個過程,全程都是vue3
源碼中的 Proxy
完成的。
不僅如此 vue3
更是推出瞭更貼近原生js的語法,點贊!!!!!!
<script setup> import { reactive, ref} from "vue"; // 漸進式更新:ref api let val = ref(""); let todos = reactive([ { id: 0, title: "吃飯", done: false, }, { id: 1, title: "睡覺", done: false, }, ]); function addTodo() { todos.push({ id: todos.length, title: val.value, done: false, }); val.value = ""; } </script>
其實到這裡,vue
技術棧的同學一定暗自得意,蹦出一句vue yes
! 可惜這麼好的庫也有存在的問題,vue2響應式Object.defineProperty
無法監聽數組下標和對象後新增的屬性值變化已是老生常談,vue3采用瞭 Proxy Api
解決這些問題的同時,也帶來瞭新的問題,如reactive
隻能傳對象(react useState
簡單復雜值都可以),而官方推薦的ref卻需要通過 .value才能獲取值,這著實讓社區炸鍋,為此vue團隊迫於壓力不得不推出 toRefs
(感興趣的同學可以瞭解一下,之前線下我和藝寶探討過)。
5、事件處理(@Click vs onClick)
5.1 vue
vue
中使用 v-on
(簡寫為:) 指令監聽 DOM 事件,並在觸發時運行一些 JavaScript
代碼。通常使用v-on接收一個需要調用的方法名稱。
<div @click="helloShanghai">welcome</div> <div @click="helloShanghai('hello')">welcome</div>
訪問原生DOM事件,可以將$event
顯式傳入method
中
<div @click="helloShanghai('hello', $event)">welcome</div>
普通元素 addEventListener
,組件$on
5.2 react
React
元素的事件處理和 DOM 元素的很相似,但是有一點語法上的不同:
React
事件的命名采用小駝峰式,而不是純小寫。- 使用 JSX 語法時你需要傳入一個函數作為事件處理函數,而不是一個字符串。
<div onClick={this.handleClick}>Click me</div> <div onClick={this.handleClick.bind(this)}>Click me</div> <div onClick={()=>{this.handleClick()})}>Click me</div> <div onClick={this.handleClick()}>Click me</div><!-- 錯誤寫法>
react16將合成事件掛載到 document
上,17版本後為root
根元素。
6、組件化
Vue
鼓勵寫近似常規HTML
的模板。寫起來很接近標準 HTML元素,隻是多瞭一些屬性。 React推薦你所有的模板通用JavaScript
的語法擴展——JSX書寫。
7、構建工具
React ==> Create React APP Vue ==> vue-cli
8、其他
當然還有其他的一些比較,諸如vue的插槽(slot)與react的props.children
。 生命周期:getDerivedStateFormProps
、getSnapshotBeforeUpdate
我的看法:
1、react在中後臺項目中由於在處理復雜的業務邏輯或組件的復用問題比vue優雅而被人認可,但也更需要團隊技術整體比較給力,領頭大佬的設計與把關能力要更優秀,因此開發成本更大。 2、
vue
更友好更易上手的寫法著稱,更友好的api更親民的設計讓開發成本與效率大大提升。 3、另一方面,vue因為規定瞭很多api,規范瞭開發者,同時也一定程度上限制瞭開發者的發散思維;而react
因為更少的a pi提高瞭開發者的創造力,同時也因為每個react
開發者對react
有不同的理解而產生不同的代碼風格。 4、vue與react在發展長河中越發成熟,深思熟慮後覺得兩者不管在移動端或大型中後臺都是非常可行的,關於框架好壞的問題,其實更應該思考的是公司團隊想要用什麼技術棧、自己喜歡與擅長什麼技術棧等。
五、全傢桶
到此這篇關於vue
與react
詳細的文章就介紹到這瞭,更多相關vue與react
內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!