vue與react詳細(xì)
一、全景圖
二、背景
1、react:專業(yè)
- 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發(fā)布 正式支持 hooks語(yǔ)法。
- 2020 年 10 月 22 日 v17
解決問(wèn)題:
React
用來(lái)解決什么問(wèn)題,官方網(wǎng)站上這樣說(shuō)道: We build React to solve one problem:building large applications with data that changes over time.
2、vue:傳奇
發(fā)端于2013年的個(gè)人項(xiàng)目,但如今已然成為世界三大前端框架之一,在中國(guó)大陸更是前端首選。(面試官問(wèn):為什么你學(xué)習(xí)用vue?答:因?yàn)閻?ài)國(guó)!)
- 2013年,在
Google
工作的尤雨溪,受到Angular
的啟發(fā),從中提取自己所喜歡的部分,開(kāi)發(fā)出了一款輕量框架,最初命名為Seed
。 - 同年12月,這粒種子發(fā)芽了,更名為
Vue
(因?yàn)槭莻€(gè)視圖層庫(kù),而 vue 是view
的法語(yǔ)),版本號(hào)是0.6.0。 - 2014.01.24,Vue正式對(duì)外發(fā)布,版本號(hào)是0.8.0。
- 發(fā)布于2014.02.25的0.9.0,有了自己的代號(hào):
Animatrix
,這個(gè)名字來(lái)自動(dòng)畫(huà)版的《駭客帝國(guó)》,此后,重要的版本都會(huì)有自己的代號(hào)。 - 0.12.0發(fā)布于2015.06.13,代號(hào)
Dragon Ball
(龍珠),這一年,Vue迎來(lái)了大爆發(fā),Laravel
社區(qū)(一款流行的 PHP 框架的社區(qū))首次使用 Vue,Vue
在JS社區(qū)也打響了知名度。 1.0.0 Evangelion
(新世紀(jì)福音戰(zhàn)士)是Vue
歷史上的第一個(gè)里程碑。同年,vue-router
(2015-08-18)、vuex(2015-11-28)、vue-cli
(2015-12-27)相繼發(fā)布,標(biāo)志著Vue
從一個(gè)視圖層庫(kù)發(fā)展為一個(gè)漸進(jìn)式框架。很多前端同學(xué)也是從這個(gè)版本開(kāi)始成為Vue的用戶(vue1純純的響應(yīng)式)。- 2016年10月1日 2.0.0
Ghost in the Shell
(攻殼機(jī)動(dòng)隊(duì))是第二個(gè)重要的里程碑,它吸收了React
的Virtual Dom
方案,還支持服務(wù)端渲染。 - 2019年2月4日 在2.6發(fā)布之前的很長(zhǎng)一段時(shí)間,
Vue
核心團(tuán)隊(duì)都在忙著vue-cli3.0
的開(kāi)發(fā),積攢了不少需求,發(fā)布了vue2
倒數(shù)第二個(gè)的版本(2020年發(fā)布) - 2020年09月18日 帶著成為任何人都可以快速學(xué)習(xí)、易于接近的框架的使命
vue3
它來(lái)了,同年還推出了新時(shí)代打包工具vite(未來(lái)可能會(huì)取代webpack
)
vue群眾基礎(chǔ)圖 如下圖:
三、技術(shù)思想
react
整體上是函數(shù)式的思想,組件使用jsx語(yǔ)法,all in js
,將html
與css全都融入javaScript
,jsx語(yǔ)法相對(duì)來(lái)說(shuō)更加靈活。
vue的整體思想仍然是擁抱經(jīng)典的html
(結(jié)構(gòu))+css(表現(xiàn))+js(行為)的形式,vue鼓勵(lì)開(kāi)發(fā)者使用template
模板,并提供指令供開(kāi)發(fā)者使用如v-if
、v-show
、v-for等指令,因此在開(kāi)發(fā)vue應(yīng)用的時(shí)候會(huì)有一種在寫(xiě)經(jīng)典web應(yīng)用(結(jié)構(gòu)、表現(xiàn)、行為分離)的感覺(jué)。
一些老生常談的 數(shù)據(jù)管理(props
、data vs state
)、組件寫(xiě)法、生命周期異同這里就不比較了。
1、key的異同為例
1、react
與vue在列表加key的問(wèn)題上最終目的是一致的:更準(zhǔn)確、更快地拿到oldVnode
中對(duì)應(yīng)的vnode節(jié)點(diǎn),提高性能。但是它們實(shí)現(xiàn)的算法卻有一定的差異。
1.1 react
React在渲染數(shù)組時(shí)如果子組件沒(méi)有提供key,會(huì)默認(rèn)將循環(huán)的index作為key來(lái)用作第一次渲染。 源碼本質(zhì)上就是暴力比較法:由于單鏈表fiber無(wú)法使用雙指針?biāo)惴ǎ詿o(wú)法對(duì)算法使用雙指針優(yōu)化??傮w上經(jīng)歷兩輪遍歷,第一輪遍歷:處理更新的節(jié)點(diǎn)。第二輪遍歷:處理剩下的不屬于更新的節(jié)點(diǎn)。
為了降低算法復(fù)雜度,React的diff會(huì)預(yù)設(shè)限制:
只對(duì)同級(jí)元素進(jìn)行Diff。如果一個(gè)DOM節(jié)點(diǎn)在前后兩次更新中跨越了層級(jí),那么React不會(huì)嘗試復(fù)用他。
兩個(gè)不同類型的元素會(huì)產(chǎn)生出不同的樹(shù)。如果元素由div變?yōu)閜,React
會(huì)銷毀div及其子孫節(jié)點(diǎn),并新建p及其子孫節(jié)點(diǎn)。
先判斷key再判斷type,兩者相同則為同一節(jié)點(diǎn)。更新>新增/刪除
1.2 vue
vue
在diff性能方面要強(qiáng)于react,當(dāng)我認(rèn)真閱讀了源碼與書(shū)籍后,佩服至極, 力扣算法題--最長(zhǎng)遞增子序列 舉個(gè)例子吧:以數(shù)組[2, 11, 6, 8, 1]為例:最終輸出的結(jié)果為[0, 2, 3],表示最強(qiáng)增長(zhǎng)序列的索引分別是0,2,3;對(duì)應(yīng)的值是2,6,8。換句話說(shuō),在這個(gè)數(shù)組中最長(zhǎng)連續(xù)增長(zhǎng)的值就是數(shù)組中的2,6,8三個(gè)元素。
那么vue3費(fèi)了這么大的力氣,使用這個(gè)方法的目的是什么呢? Vue2在DOM-Diff
過(guò)程中,優(yōu)先處理特殊場(chǎng)景的情況,即頭頭比對(duì),頭尾比對(duì),尾頭比對(duì)等。
而Vue3在DOM-Diff
過(guò)程中,根據(jù) newIndexToOldIndexMap
新老節(jié)點(diǎn)索引列表找到最長(zhǎng)穩(wěn)定序列,通過(guò)最長(zhǎng)增長(zhǎng)子序列的算法比對(duì),找出新舊節(jié)點(diǎn)中不需要移動(dòng)的節(jié)點(diǎn),原地復(fù)用,僅對(duì)需要移動(dòng)或已經(jīng)patch
(新增刪除節(jié)點(diǎn)等操作)節(jié)點(diǎn)進(jìn)行操作,最大限度地提升替換效率,相比于Vue2版本是質(zhì)的提升!
2、diff的宏觀比較
2.1 react
在react中如果某個(gè)組件的狀態(tài)發(fā)生改變,react會(huì)把此組件以及此組件的所有后代組件重新渲染,不過(guò)重新渲染并不代表會(huì)全部丟棄上一次的渲染結(jié)果,react
還是會(huì)通過(guò)diff
去比較兩次的虛擬dom最后patch
到真實(shí)的dom上。雖然如此,如果組件樹(shù)過(guò)大,diff其實(shí)還是會(huì)有一部分的開(kāi)銷。react
內(nèi)部通過(guò) fiber
優(yōu)化 diff算法,外部建議開(kāi)發(fā)者使用 shouldComponentUpdate pureComponent
來(lái)規(guī)避問(wèn)題。
2.2 vue
vue2的響應(yīng)式是Object.defineProperty實(shí)現(xiàn)的,并且重寫(xiě)getter``setter等一系列操作實(shí)現(xiàn)觀察者模式,一旦數(shù)據(jù)發(fā)生變化,不會(huì)像react一樣去比較整顆組件樹(shù),而是去更新數(shù)據(jù)狀態(tài)變化了的組件實(shí)例。
3、生命周期
3.1 react 生命周期
old 15.x-16
new 16+
其他:componentDidCatch
React
生命周期的命名一直都是非常語(yǔ)義化(小聲bb:真是又臭又長(zhǎng)又難記)
3.2 vue生命周期
4、函數(shù)式編程
雙方都做出了大規(guī)模的改動(dòng),雖然源碼不同,但設(shè)計(jì)思想以及代碼簡(jiǎn)易程度來(lái)看,確實(shí)都在進(jìn)步。
4.1 react hooks
原先繁瑣的 compomentDidUpdate
生命周期 =》 useEffect
,雖然不完全相同,但在大多數(shù)場(chǎng)景中,從開(kāi)發(fā)者層面看待,我們更多是關(guān)心props
或者state中的數(shù)據(jù)變化之后,會(huì)產(chǎn)生了什么后果(副作用),省去了開(kāi)發(fā)者自己比較前后值的過(guò)程。(這應(yīng)該是react借鑒vue watch
)
4.2 vue3 組合式api
vue3
組合式api借鑒了react hooks
中的部分思想,不得不說(shuō),青出于藍(lán)而勝于藍(lán),再加上框架自己也做出了很多優(yōu)化工作,在性能上是react比不上的。
function() { useEffect(()=>{ // 當(dāng)demo發(fā)生變化時(shí)觸發(fā) 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 } } }
由于初始化時(shí)源碼內(nèi)部的響應(yīng)式機(jī)制的緣故,新APIwatchEffect
甚至都不需要監(jiān)聽(tīng)是誰(shuí)發(fā)生了變化就可以觸發(fā)副作用,因?yàn)楸O(jiān)聽(tīng)的這個(gè)過(guò)程,全程都是vue3
源碼中的 Proxy
完成的。
不僅如此 vue3
更是推出了更貼近原生js的語(yǔ)法,點(diǎn)贊?。。。。。?/p>
<script setup> import { reactive, ref} from "vue"; // 漸進(jìn)式更新:ref api let val = ref(""); let todos = reactive([ { id: 0, title: "吃飯", done: false, }, { id: 1, title: "睡覺(jué)", done: false, }, ]); function addTodo() { todos.push({ id: todos.length, title: val.value, done: false, }); val.value = ""; } </script>
其實(shí)到這里,vue
技術(shù)棧的同學(xué)一定暗自得意,蹦出一句vue yes
! 可惜這么好的庫(kù)也有存在的問(wèn)題,vue2響應(yīng)式Object.defineProperty
無(wú)法監(jiān)聽(tīng)數(shù)組下標(biāo)和對(duì)象后新增的屬性值變化已是老生常談,vue3采用了 Proxy Api
解決這些問(wèn)題的同時(shí),也帶來(lái)了新的問(wèn)題,如reactive
只能傳對(duì)象(react useState
簡(jiǎn)單復(fù)雜值都可以),而官方推薦的ref卻需要通過(guò) .value才能獲取值,這著實(shí)讓社區(qū)炸鍋,為此vue團(tuán)隊(duì)迫于壓力不得不推出 toRefs
(感興趣的同學(xué)可以了解一下,之前線下我和藝寶探討過(guò))。
5、事件處理(@Click vs onClick)
5.1 vue
vue
中使用 v-on
(簡(jiǎn)寫(xiě)為:) 指令監(jiān)聽(tīng) DOM 事件,并在觸發(fā)時(shí)運(yùn)行一些 JavaScript
代碼。通常使用v-on接收一個(gè)需要調(diào)用的方法名稱。
<div @click="helloShanghai">welcome</div> <div @click="helloShanghai('hello')">welcome</div>
訪問(wèn)原生DOM事件,可以將$event
顯式傳入method
中
<div @click="helloShanghai('hello', $event)">welcome</div>
普通元素 addEventListener
,組件$on
5.2 react
React
元素的事件處理和 DOM 元素的很相似,但是有一點(diǎn)語(yǔ)法上的不同:
React
事件的命名采用小駝峰式,而不是純小寫(xiě)。- 使用 JSX 語(yǔ)法時(shí)你需要傳入一個(gè)函數(shù)作為事件處理函數(shù),而不是一個(gè)字符串。
<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><!-- 錯(cuò)誤寫(xiě)法>
react16將合成事件掛載到 document
上,17版本后為root
根元素。
6、組件化
Vue
鼓勵(lì)寫(xiě)近似常規(guī)HTML
的模板。寫(xiě)起來(lái)很接近標(biāo)準(zhǔn) HTML元素,只是多了一些屬性。 React推薦你所有的模板通用JavaScript
的語(yǔ)法擴(kuò)展——JSX書(shū)寫(xiě)。
7、構(gòu)建工具
React ==> Create React APP Vue ==> vue-cli
8、其他
當(dāng)然還有其他的一些比較,諸如vue的插槽(slot)與react的props.children
。 生命周期:getDerivedStateFormProps
、getSnapshotBeforeUpdate
我的看法:
1、react在中后臺(tái)項(xiàng)目中由于在處理復(fù)雜的業(yè)務(wù)邏輯或組件的復(fù)用問(wèn)題比vue優(yōu)雅而被人認(rèn)可,但也更需要團(tuán)隊(duì)技術(shù)整體比較給力,領(lǐng)頭大佬的設(shè)計(jì)與把關(guān)能力要更優(yōu)秀,因此開(kāi)發(fā)成本更大。 2、
vue
更友好更易上手的寫(xiě)法著稱,更友好的api更親民的設(shè)計(jì)讓開(kāi)發(fā)成本與效率大大提升。 3、另一方面,vue因?yàn)橐?guī)定了很多api,規(guī)范了開(kāi)發(fā)者,同時(shí)也一定程度上限制了開(kāi)發(fā)者的發(fā)散思維;而react
因?yàn)楦俚腶 pi提高了開(kāi)發(fā)者的創(chuàng)造力,同時(shí)也因?yàn)槊總€(gè)react
開(kāi)發(fā)者對(duì)react
有不同的理解而產(chǎn)生不同的代碼風(fēng)格。 4、vue與react在發(fā)展長(zhǎng)河中越發(fā)成熟,深思熟慮后覺(jué)得兩者不管在移動(dòng)端或大型中后臺(tái)都是非??尚械?,關(guān)于框架好壞的問(wèn)題,其實(shí)更應(yīng)該思考的是公司團(tuán)隊(duì)想要用什么技術(shù)棧、自己喜歡與擅長(zhǎng)什么技術(shù)棧等。
五、全家桶
到此這篇關(guān)于vue
與react
詳細(xì)的文章就介紹到這了,更多相關(guān)vue與react
內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue3中reactive函數(shù)toRef函數(shù)ref函數(shù)簡(jiǎn)介
- 關(guān)于怎么在vue項(xiàng)目里寫(xiě)react詳情
- 手摸手教你實(shí)現(xiàn)Vue3 Reactivity
- Vue3.0中Ref與Reactive的區(qū)別示例詳析
- Vue3中ref與reactive的詳解與擴(kuò)展
- 詳解vue3中setUp和reactive函數(shù)的用法
- vue3組合API中setup、 ref、reactive的使用大全
- 詳解React Angular Vue三大前端技術(shù)
- Vue與React的區(qū)別和優(yōu)勢(shì)對(duì)比
- Vue和React有哪些區(qū)別
相關(guān)文章
如何讓別人訪問(wèn)本地運(yùn)行的vue項(xiàng)目
這篇文章主要介紹了如何讓別人訪問(wèn)本地運(yùn)行的vue項(xiàng)目,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vuejs2.0實(shí)現(xiàn)分頁(yè)組件使用$emit進(jìn)行事件監(jiān)聽(tīng)數(shù)據(jù)傳遞的方法
這篇文章主要介紹了vuejs2.0實(shí)現(xiàn)分頁(yè)組件使用$emit進(jìn)行事件監(jiān)聽(tīng)數(shù)據(jù)傳遞的方法,非常不錯(cuò),具有參考借鑒價(jià)值,,需要的朋友可以參考下2017-02-02如何用webpack4帶你實(shí)現(xiàn)一個(gè)vue的打包的項(xiàng)目
這篇文章主要介紹了如何用webpack4帶你實(shí)現(xiàn)一個(gè)vue的打包的項(xiàng)目,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06教你三分鐘掌握Vue過(guò)濾器filters及時(shí)間戳轉(zhuǎn)換
這篇文章教你三分鐘掌握Vue過(guò)濾器filters及時(shí)間戳轉(zhuǎn)換,本文將結(jié)合時(shí)間戳轉(zhuǎn)換的例子帶你快速了解filters的用法,需要的朋友可以參考下2023-03-03Vue表單驗(yàn)證插件Vue Validator使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Vue表單驗(yàn)證插件Vue Validator使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Vue3實(shí)現(xiàn)下拉選擇框多選功能的方法詳解
在vue的實(shí)際開(kāi)發(fā)過(guò)程中,我們?nèi)绾螌⒁赃x中的值直接渲染到頁(yè)面中,下面這篇文章主要給大家介紹了關(guān)于Vue3實(shí)現(xiàn)下拉選擇框多選功能的相關(guān)資料,需要的朋友可以參考下2023-09-09vue-iview動(dòng)態(tài)新增和刪除的方法
這篇文章主要為大家詳細(xì)介紹了vue-iview動(dòng)態(tài)新增和刪除的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06解決Vue路由導(dǎo)航報(bào)錯(cuò):NavigationDuplicated:?Avoided?redundant?navig
這篇文章主要給大家介紹了關(guān)于解決Vue路由導(dǎo)航報(bào)錯(cuò):NavigationDuplicated:?Avoided?redundant?navigation?to?current?location的相關(guān)資料,這是最近做項(xiàng)目時(shí)候遇到的一個(gè)問(wèn)題,現(xiàn)將解決辦法分享出來(lái),需要的朋友可以參考下2023-01-01