一篇Vue、React重點(diǎn)詳解大全
Vue
生命周期
vue2:
總共分為8個(gè)階段:創(chuàng)建前/后,載入前/后,更新前/后,銷毀前/后。
- 創(chuàng)建前/后: 在beforeCreate階段,由于還未初始化,vue實(shí)例的掛載元素el和數(shù)據(jù)對(duì)象data都為undefined。在created階段,vue實(shí)例的數(shù)據(jù)對(duì)象data有了,el還沒有。
- 載入前/后:在beforeMount階段,vue實(shí)例的$el和data都初始化了,但掛載之前還是為虛擬的dom節(jié)點(diǎn),data.message還未替換。在mounted階段,vue實(shí)例掛載完成,data.message成功渲染。
- 更新前/后:當(dāng)data變化時(shí),會(huì)觸發(fā)beforeUpdate和updated方法。
- 銷毀前/后:在執(zhí)行destroy方法后,對(duì)data的改變不會(huì)再觸發(fā)周期函數(shù),說明此時(shí)vue實(shí)例已經(jīng)解除了事件監(jiān)聽以及和dom的綁定,但是dom結(jié)構(gòu)依然存在。
vue3:
- beforeCreate -> 使用 setup()
- created -> 使用 setup()
- beforeMount -> onBeforeMount
- mounted -> onMountedbefore
- Update -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
MVVM
mvvm是一種設(shè)計(jì)思想。
Model代表數(shù)據(jù)模型,可以在model中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯;
view表示ui組件,負(fù)責(zé)將數(shù)據(jù)模型轉(zhuǎn)換為ui展現(xiàn)出來(lái),它做的是數(shù)據(jù)綁定的聲明、 指令的聲明、 事件綁定的聲明。
而viewModel是一個(gè)同步view和model的對(duì)象。
在mvvm框架中,view和model之間沒有直接的關(guān)系,它們是通過viewModel來(lái)進(jìn)行交互的。
mvvm不需要手動(dòng)操作dom,只需要關(guān)注業(yè)務(wù)邏輯就可以了。
mvvm 的核心是數(shù)據(jù)劫持、數(shù)據(jù)代理、數(shù)據(jù)編譯和"發(fā)布訂閱模式"。
mvvm和mvc的區(qū)別在于:mvvm是數(shù)據(jù)驅(qū)動(dòng)的,而MVC是dom驅(qū)動(dòng)的。
mvvm的優(yōu)點(diǎn)在于不用操作大量的dom,不需要關(guān)注model和view之間的關(guān)系,而MVC需要在model發(fā)生改變時(shí),需要手動(dòng)的去更新view。
大量操作dom使頁(yè)面渲染性能降低,使加載速度變慢,影響用戶體驗(yàn)。
雙向綁定原理
vue2是利用ES5的Object.defineProperty,
局限:只能監(jiān)聽對(duì)象屬性的變化;不能利用索引直接設(shè)置一個(gè)數(shù)組項(xiàng),也不能修改數(shù)組的長(zhǎng)度
Object.defineProperty(object, "key", { get() { return bValue; }, set(newValue) { bValue = newValue; }, enumerable : true, configurable : true });
Vue3.0中的響應(yīng)式采用了ES6中的 Proxy 方法,可以監(jiān)聽對(duì)象某個(gè)屬性值的變化,還可以監(jiān)聽對(duì)象屬性的新增和刪除,而且還可以監(jiān)聽數(shù)組。
var proxy = new Proxy({}, { get: function(target, propKey) { return 35; } set: function(obj, prop, value) { obj[prop] = value; return true; } });
虛擬dom
虛擬dom本質(zhì)是將目標(biāo)所需的 UI 通過數(shù)據(jù)結(jié)構(gòu)“虛擬”地表示出來(lái),保存在內(nèi)存中,然后將真實(shí)的 DOM 與之保持同步。
在渲染之前,會(huì)使用新生成的虛擬節(jié)點(diǎn)和上一次生成的虛擬節(jié)點(diǎn)進(jìn)行對(duì)比,只渲染不同的部分。
虛擬DOM在vue中主要提供與真實(shí)節(jié)點(diǎn)對(duì)應(yīng)的虛擬節(jié)點(diǎn)vnode,然后需要將vnode和oldVnode進(jìn)行比對(duì),然后更新視圖,對(duì)比兩個(gè)虛擬節(jié)點(diǎn)的算法是patch算法。
(在 vue 里面diff 算法就是通過 patch 函數(shù)來(lái)完成的,所有有的時(shí)候也叫 patch 算法.)
v-for為什么要用key
Vue 默認(rèn)按照“就地更新”的策略來(lái)更新通過 v-for 渲染的元素列表。當(dāng)數(shù)據(jù)項(xiàng)的順序改變時(shí),Vue 不會(huì)隨之移動(dòng) DOM 元素的順序,而是就地更新每個(gè)元素,確保它們?cè)谠局付ǖ乃饕恢蒙箱秩尽?/p>
key能提高diff效率其實(shí)是需要分情況的。
不用 key:
就地復(fù)用節(jié)點(diǎn)。在比較新舊兩個(gè)節(jié)點(diǎn)是否是同一個(gè)節(jié)點(diǎn)的過程中會(huì)判斷成新舊兩個(gè)節(jié)點(diǎn)是同一個(gè)節(jié)點(diǎn),因?yàn)?a.key 和 b.key 都是 undefined。
所以不會(huì)重新創(chuàng)建節(jié)點(diǎn)和刪除節(jié)點(diǎn),只會(huì)在節(jié)點(diǎn)的屬性層面上進(jìn)行比較和更新。所以可能在某種程度上(創(chuàng)建和刪除節(jié)點(diǎn)方面)會(huì)有渲染性能上的提升;無(wú)法維持組件的狀態(tài)。
由于就地復(fù)用節(jié)點(diǎn)的關(guān)系,可能在維持組件狀態(tài)方面會(huì)導(dǎo)致不可預(yù)知的錯(cuò)誤,比如無(wú)法維持改組件的動(dòng)畫效果、開關(guān)等狀態(tài);也有可能會(huì)帶來(lái)性能下降。
因?yàn)槭侵苯泳偷貜?fù)用節(jié)點(diǎn),如果修改的組件,需要復(fù)用的很多節(jié)點(diǎn),順序又和原來(lái)的完全不同的話,那么創(chuàng)建和刪除的節(jié)點(diǎn)數(shù)量就會(huì)比帶 key 的時(shí)候增加很多,性能就會(huì)有所下降;
用 key:
維持組件的狀態(tài),保證組件的復(fù)用。因?yàn)橛?key 唯一標(biāo)識(shí)了組件,不會(huì)在每次比較新舊兩個(gè)節(jié)點(diǎn)是否是同一個(gè)節(jié)點(diǎn)的時(shí)候直接判斷為同一個(gè)節(jié)點(diǎn),而是會(huì)繼續(xù)在接下來(lái)的節(jié)點(diǎn)中找到 key 相同的節(jié)點(diǎn)去比較,能找到相同的 key 的話就復(fù)用節(jié)點(diǎn),不能找到的話就增加或者刪除節(jié)點(diǎn)。
查找性能上的提升。
有 key 的時(shí)候,會(huì)生成 hash,這樣在查找的時(shí)候就是 hash 查找了,基本上就是 O(1) 的復(fù)雜度。
節(jié)點(diǎn)復(fù)用帶來(lái)的性能提升。因?yàn)橛?key 唯一標(biāo)識(shí)了組件,所以會(huì)盡可能多的對(duì)組件進(jìn)行復(fù)用(盡管組件順序不同),那么創(chuàng)建和刪除節(jié)點(diǎn)數(shù)量就會(huì)變少,這方面的消耗就會(huì)下降,帶來(lái)性能的提升。
總結(jié):性能提升不能只考慮一方面,不是 diff 快了性能就快,不是增刪節(jié)點(diǎn)少了性能就快,不考慮量級(jí)的去評(píng)價(jià)性能,都只是泛泛而談。
key也不能是li元素的index,因?yàn)榧僭O(shè)我們給數(shù)組前插入一個(gè)新元素,它的下標(biāo)是0,那么和原來(lái)的第一個(gè)元素重復(fù)了,整個(gè)數(shù)組的key都發(fā)生了改變,這樣就跟沒有key的情況一樣了。
nextTick
vue 采用的異步更新策略,當(dāng)監(jiān)聽到數(shù)據(jù)發(fā)生變化的時(shí)候不會(huì)立即去更新DOM,而是開啟一個(gè)任務(wù)隊(duì)列,并緩存在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)變更;
這種做法帶來(lái)的好處就是可以將多次數(shù)據(jù)更新合并成一次,減少操作DOM的次數(shù),如果不采用這種方法,假設(shè)數(shù)據(jù)改變100次就要去更新100次DOM,而頻繁的DOM更新是很耗性能的。
nextTick 接收一個(gè)回調(diào)函數(shù)作為參數(shù),并將這個(gè)回調(diào)函數(shù)延遲到DOM更新后才執(zhí)行;
使用場(chǎng)景:想要操作 基于最新數(shù)據(jù)生成的DOM 時(shí),就將這個(gè)操作放在 nextTick 的回調(diào)中;
實(shí)現(xiàn)原理:將傳入的回調(diào)函數(shù)包裝成異步任務(wù),異步任務(wù)又分微任務(wù)和宏任務(wù),為了盡快執(zhí)行所以優(yōu)先選擇微任務(wù);
v-show、v-if的區(qū)別
v-if 是“真實(shí)的”按條件渲染,因?yàn)樗_保了在切換時(shí),條件區(qū)塊內(nèi)的事件監(jiān)聽器和子組件都會(huì)被銷毀與重建。
v-if 也是惰性的:如果在初次渲染時(shí)條件值為 false,則不會(huì)做任何事。條件區(qū)塊只有當(dāng)條件首次變?yōu)?true 時(shí)才被渲染。
相比之下,v-show 簡(jiǎn)單許多,元素?zé)o論初始條件如何,始終會(huì)被渲染,只有 CSS display 屬性會(huì)被切換。
總的來(lái)說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要頻繁切換,則使用 v-show 較好;如果在運(yùn)行時(shí)綁定條件很少改變,則 v-if 會(huì)更合適。
實(shí)現(xiàn)方式:v-if會(huì)調(diào)用addIfCondition方法,生成vnode的時(shí)候會(huì)忽略對(duì)應(yīng)節(jié)點(diǎn),render的時(shí)候就不會(huì)渲染;
v-show會(huì)生成vnode,render的時(shí)候也會(huì)渲染成真實(shí)節(jié)點(diǎn),只是在render過程中會(huì)在節(jié)點(diǎn)的屬性中修改show屬性值,也就是常說的display;
vue單頁(yè)面應(yīng)用如何首頁(yè)優(yōu)化
VUE首頁(yè)加載過慢,其原因是因?yàn)樗且粋€(gè)單頁(yè)應(yīng)用,需要將所有需要的資源都下載到瀏覽器端并解析。
- cdn加速
- 路由懶加載
- 首頁(yè)加 loading 或 骨架屏 (僅僅是優(yōu)化體驗(yàn))
- 首頁(yè)使用SSR,其他頁(yè)面前端渲染
- 優(yōu)化js體積,使用分包等策略減少chunk-vendors.js的體積
- 優(yōu)化第三方庫(kù),按需引入,減少不必要的引入
- 圖片壓縮,使用字體圖標(biāo)等
- 開啟gizp壓縮;
- 使網(wǎng)站的css、js 、xml、html 等靜態(tài)資源在傳輸時(shí)進(jìn)行壓縮,經(jīng)過Gzip壓縮后資源可以變?yōu)樵瓉?lái)的30%甚至更小,盡管這樣會(huì)消耗一定的cpu資源,但是會(huì)節(jié)約大量的出口帶寬來(lái)提高訪問速度.
Vue 的父組件和子組件生命周期鉤子執(zhí)行順序是什么
加載渲染過程 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
子組件更新過程 父beforeUpdate->子beforeUpdate->子updated->父updated
父組件更新過程 父beforeUpdate->父updated
銷毀過程 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
Vue 中的 computed 是如何實(shí)現(xiàn)的
總結(jié):computed本身是通過代理的方式代理到組件實(shí)例上的,所以讀取計(jì)算屬性的時(shí)候,執(zhí)行的是一個(gè)內(nèi)部的getter,而不是用戶定義的方法。
computed內(nèi)部實(shí)現(xiàn)了一個(gè)惰性的watcher,在實(shí)例化的時(shí)候不會(huì)去求值,其內(nèi)部通過dirty屬性標(biāo)記計(jì)算屬性是否需要重新求值。
當(dāng)computed依賴的任一狀態(tài)(不一定是return中的)發(fā)生變化,都會(huì)通知這個(gè)惰性watcher,讓它把dirty屬性設(shè)置為true。
所以,當(dāng)再次讀取這個(gè)計(jì)算屬性的時(shí)候,就會(huì)重新去求值。
React 不同之處
vue和react的區(qū)別
兩者都是管理全局狀態(tài)的工具庫(kù),總的來(lái)說都是讓 View 通過某種方式觸發(fā) Store 的事件或方法,Store 的事件或方法對(duì) State 進(jìn)行修改或返回一個(gè)新的 State,State 改變之后,View 發(fā)生響應(yīng)式改變。
Redux: view——>actions——>reducer——>state變化——>view變化(同步異步一樣)
Vuex: view——>commit——>mutations——>state變化——>view變化(同步操作) view——>dispatch——>actions——>mutations——>state變化——>view變化(異步操作)
vuex:
對(duì)于簡(jiǎn)單應(yīng)用來(lái)說,使用 Vuex 是繁瑣冗余,可以使用用響應(yīng)式 API 做簡(jiǎn)單狀態(tài)管理,用 reactive() 來(lái)創(chuàng)建一個(gè)響應(yīng)式對(duì)象,并在不同組件中導(dǎo)入它。
State
Vuex 使用單一狀態(tài)樹——是的,用一個(gè)對(duì)象就包含了全部的應(yīng)用層級(jí)狀態(tài)。
至此它便作為一個(gè)“唯一數(shù)據(jù)源 (SSOT)”而存在。這也意味著,每個(gè)應(yīng)用將僅僅包含一個(gè) store 實(shí)例。
單一狀態(tài)樹讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過程中也能輕易地取得整個(gè)當(dāng)前應(yīng)用狀態(tài)的快照.Vuex通過 store 選項(xiàng),把 state 注入到了整個(gè)應(yīng)用中,這樣子組件能通過 this.$store 訪問到 state 了
Mutation
更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation。
Vuex 中的 mutation 非常類似于事件:每個(gè) mutation 都有一個(gè)字符串的事件類型 (type)和一個(gè)回調(diào)函數(shù) (handler)。
這個(gè)回調(diào)函數(shù)就是我們實(shí)際進(jìn)行狀態(tài)更改的地方,并且它會(huì)接受 state 作為第一個(gè)參數(shù)。
注意:mutation 必須是同步函數(shù)
Action
Action 類似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接變更狀態(tài)。
Action 可以包含任意異步操作
Action 通過 store.dispatch 方法觸發(fā)
以上就是一篇Vue、React重點(diǎn)詳解大全的詳細(xì)內(nèi)容,更多關(guān)于Vue、React的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue3中update:modelValue的使用與不生效問題解決
現(xiàn)在vue3的使用越來(lái)越普遍了,vue3這方面的學(xué)習(xí)我們要趕上,下面這篇文章主要給大家介紹了關(guān)于vue3中update:modelValue的使用與不生效問題的解決方法,需要的朋友可以參考下2022-03-03Vue如何實(shí)現(xiàn)多頁(yè)面配置以及打包方式
這篇文章主要介紹了Vue如何實(shí)現(xiàn)多頁(yè)面配置以及打包方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vue使用lodop打印控件實(shí)現(xiàn)瀏覽器兼容打印的方法
這篇文章主要介紹了vue使用lodop打印控件實(shí)現(xiàn)瀏覽器兼容打印的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02vue 使用微信jssdk,調(diào)用微信相冊(cè)上傳圖片功能
這篇文章主要介紹了vue 使用微信jssdk,調(diào)用微信相冊(cè)上傳圖片功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-11-11如何在Vue3中實(shí)現(xiàn)自定義指令(超詳細(xì)!)
除了默認(rèn)設(shè)置的核心指令(v-model和v-show),Vue也允許注冊(cè)自定義指令,下面這篇文章主要給大家介紹了關(guān)于如何在Vue3中實(shí)現(xiàn)自定義指令的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06