1-為什么要在列表中綁定key役拴,有什么作用
? ? 組件在更新階段會對兩次vnode做比較童社,以確定走patchVnode還是create-updateParentPlaceholder-destory過程
? ? 節(jié)點(diǎn)對比的條件之一就是key值是否等價
? ? 這意味著,在不帶key值的情況下(即兩次均為undefined)程腹,vue有一定概率(如list列表)會將兩次vnode判斷為sameVnode走patchVnode復(fù)用dom節(jié)點(diǎn)
? ? 那么皇帮,假設(shè)當(dāng)前的需求是選項(xiàng)卡形式粹淋,每一個選項(xiàng)卡下都有一個list列表,我們在tab1下的列表1通過點(diǎn)擊綁定了class使其高亮匙头,那么當(dāng)選項(xiàng)卡切換到tab2后漫谷,列表1仍然是高亮狀態(tài)
2-聊聊vue的雙向數(shù)據(jù)綁定
? ? 所謂雙向綁定,即數(shù)據(jù)驅(qū)動視圖更新蹂析,同時視圖更新又能change到數(shù)據(jù)變化
? ? 數(shù)據(jù)——>視圖
? ? vue的組件創(chuàng)建會經(jīng)過init過程舔示,這將執(zhí)行initstate函數(shù)對data和props做一次處理,它將遍歷data的key執(zhí)行observe电抚,這是一次遞歸defineReactive的過程惕稻。即對每一個key通過Object.defineProperties設(shè)置攔截,在get時向dep收集watcher蝙叛,在set時通過dep notify到watcher執(zhí)行render update
? ? 視圖——數(shù)據(jù)
? ? 這表現(xiàn)在v-model指令中缩宜,我們在input、textarea中輸入的文本能驅(qū)動數(shù)據(jù)的更新。這是因?yàn)関ue在模板編譯階段將v-model解析成events+props掛載到ast節(jié)點(diǎn)上锻煌,在patch過程中將會調(diào)用updateListeners通過addeventListeners向input添加input事件妓布,當(dāng)input觸發(fā)時將調(diào)用事件更新props對應(yīng)的值,以達(dá)到視圖更新的目的
3-聊聊vuex和redux的異同點(diǎn)
? ? 兩者都是響應(yīng)式編程的狀態(tài)管理方案宋梧,都很好的解決了嵌套組件的數(shù)據(jù)傳遞問題匣沼,也都是在全局定義store,通過dispatch向reducer派發(fā)action以更新store捂龄。相比較redux來說释涛,vuex提供了直接連接reducer的方案,即commit
4-在vue中倦沧,子組件為何不可以修改父組件傳遞的props唇撬,如果修改了,vue是如何監(jiān)控到并報(bào)警告的展融?
? ? 組件在init過程中會執(zhí)行initstate函數(shù)窖认,這包括了對props的處理
? ? ? ? 可以看到,vue通過重寫Object.properties.set方法告希,當(dāng)嘗試對props修改時發(fā)出警告扑浸。這么做是為了保證數(shù)據(jù)的單項(xiàng)流,避免出錯
5-為什么vue中的mutations中不能有異步操作
? ? 因?yàn)楫惒讲僮魇怯懈弊饔玫难嗯迹墓潭ㄝ斎氩粫泄潭óa(chǎn)出喝噪,這將使得程序狀態(tài)變得不可預(yù)測
6-vue2.x中的Object.definedProperty為什么會在vue3中被Proxy替代
? ??Object.definedProperty只能劫持對象的屬性,而對于某一個屬性的嵌套則無法劫持指么,但是Proxy可以酝惧,另外就是Proxy提供的可選擇api更豐富
7-Vue組件生命周期
? ? 一個組件的創(chuàng)建,要執(zhí)行init-mount-reder-patch流程伯诬。在init過程中系奉,首先通過callhook調(diào)用beforeCreate,接著才是initState姑廉,這意味著beforeCreate時組件的狀態(tài)是不可用的缺亮,但是可以向vuex或vue-router那樣通過Vue.mixin混入一些插件能力,因?yàn)榇藭r的組件尚是"干凈的"桥言,避免了對組件造成可能性的干擾萌踱;同樣的,由于created是在initState之后号阿,故此時的狀態(tài)是可用的并鸵,因此我們可以在此向后臺發(fā)起請求獲取數(shù)據(jù)并綁定給data.key;在mount過程中將首先執(zhí)行beforeMount,此時的render函數(shù)以及被編譯但尚未執(zhí)行扔涧,故無法進(jìn)行dom操作园担;在new Watcher的過程中將會執(zhí)行到render和update届谈,走patch流程,故mounted時弯汰,dom已被創(chuàng)建艰山,因此可以通過ref指令添加dom引用;當(dāng)我們通過點(diǎn)擊事件觸發(fā)data更新時咏闪,將會由dep通知到watcher執(zhí)行run走render update曙搬,此時將會執(zhí)行beforeUpdate,由于此時的dom還未更新鸽嫂,因此我們可以copy一份舊的dom以嘗試做一次回退操作纵装;最后當(dāng)組件卸載時將會觸發(fā)beforeDestory和destoryed,這將遞歸銷毀組件据某。由于vue的模板解析只會對template中的事件進(jìn)行處理橡娄,因此我們通過ref操作dom添加的事件需要手動進(jìn)行銷毀
? ? 最后是與keep-alive相關(guān)的activited和deactivited,標(biāo)識組件的激活和凍結(jié)狀態(tài)
8-vue在v-for時給每個元素綁定事件需要使用事件代理嗎
? ? 不需要癣籽!
? ? vue對dom的事件監(jiān)聽是通過dom.addEventListener實(shí)現(xiàn)的挽唉,對組件的事件處理是通過事件總線完成的
9-vue是如何對數(shù)組做響應(yīng)式處理的?為什么通過下標(biāo)的方式不行(假設(shè)數(shù)組為[1,2,3])
? ? vue會遍歷data的每一個key調(diào)用observe才避,當(dāng)為數(shù)組時,實(shí)例化observe
? 即調(diào)用
? ? 可以看到這會進(jìn)入新一輪的observe
? ? 對于我們的數(shù)組[1,2,3,4]而言氨距,每一個key是基本類型桑逝,因此vue直接return,并未對數(shù)組的每一個key做響應(yīng)式處理
? ? 那么數(shù)組的響應(yīng)式又是如何做到的呢俏让,在observe實(shí)例化過程中楞遏,針對數(shù)組調(diào)用了protoAugment或copyAugment方法,這將我們數(shù)組的原型鏈指向了arrayMethods對象首昔,該對象通過methodsToPatch進(jìn)行了重寫
? ? 因此寡喝,當(dāng)我們對數(shù)組執(zhí)行push/splice操作時能觸發(fā)更新
10-為什么data應(yīng)該是一個函數(shù)
? ? 在init過程中有對data做處理,當(dāng)為函數(shù)時會執(zhí)行g(shù)etData通過call語法將this指向當(dāng)前實(shí)例勒奇,它將返回一個獨(dú)一無二的引用類型
? ? 當(dāng)組件中存在子組件時预鬓,在render過程中將會通過Vue.extend構(gòu)建子組件構(gòu)造器,在這一過程中將會對我們的配置項(xiàng)進(jìn)行合并赊颠,如果data不是一個函數(shù)格二,vue會提示警告
? ? 這是因?yàn)椋?dāng)組件被作為公共組件使用時竣蹦,對象形式的data會被共享顶猜,這意味著,在a處的修改會影響b處的展示
11-nextTick的實(shí)現(xiàn)
? ? 當(dāng)組件更新時會通過dep.notify到watcher的update痘括,這將watcher push進(jìn)隊(duì)列
? ? 并手動調(diào)用nextTick长窄,傳入flushSchedulerQueue
? ? 而這實(shí)際上是利用了異步api滔吠,將我們的回調(diào)隊(duì)列延后到主線之后執(zhí)行
12-computed是如何實(shí)現(xiàn)的
? ? computed watcher會對依賴的變化做判斷,只有依賴變化時才會重新計(jì)算挠日。我們知道當(dāng)data中的數(shù)據(jù)被修改時會觸發(fā)watcher的update疮绷,這將會把dirty置為true
? ? 那么當(dāng)在render過程中訪問到computed.key時將會觸發(fā)computedGetter,這將觸發(fā)computed重新求值
? ? 并在計(jì)算后重新置為false
本人能力有限肆资,如有錯誤矗愧,歡迎指正喲~~