VUE面試題系列03(帶數字,帶序號)
VUE面試題系列03(帶數字,帶序號),前端面試題
24、為何vue採用非同步渲染?
1、vue採用非同步佇列渲染是為了提高效能,在非同步隊裡會去掉重複的無效的渲染。
當vue中的資料發生改變後,vue框架會把該資料引起的dom更新放入非同步佇列( 緩衝在同一事件迴圈中發生的所有資料變更 ),進行排隊。 如果同一個 watcher 被多次觸發,只會被推入到佇列中一次 。 這種在緩衝時去除重複資料對於避免不必要的計算和 DOM 操作是非常重要的 。
2、如果不採用 非同步渲染,而是在資料發生改變後,立即更新dom,如果有重複無效的渲染,那麼,就會造成效能的浪費。
25、nextTick實現原理?
1)、為什麼用Vue.nextTick()
首先,JS是單執行緒的,那麼,它如何處理非同步操作。
-
所有同步任務都在主執行緒上執行,形成一個執行棧。
-
主執行緒之外,會存在一個任務佇列,只要非同步任務有了結果,就在任務佇列中放置一個事件(所以,也叫事件佇列),進行排隊(處於等待狀態)。
-
當執行棧中的所有同步任務執行完後,就會讀取任務佇列(事件佇列)中的任務(事件)。即:任務佇列中的任務就結束了等待狀態,進入執行棧。
-
主執行緒不斷重複第三步。直到任務佇列和執行棧裡的程式碼執行完畢。
其次,vue更新DOM的思路。使用的就是非同步更新佇列,所以,就使用了事件迴圈。目的是提高效能,避免無效的重複的DOM更新。即:vue中更新資料後,並不會立即更新DOM,而是把資料引起的DOM更新放入到非同步更新佇列裡。等待下次事件迴圈(tick),並在兩個tick之間進行UI渲染。這樣程式設計師就不能在更改資料後,立即獲取更新後的DOM,也不知道什麼時候DOM能夠更新。基於此,vue提供了nextTick函式。讓程式設計師操作更新後DOM的程式碼放入到nextTick的回撥函式裡。由nextTick內部,在更新完DOM後,呼叫回撥函式。
示例程式碼:
this.msg = "hello"
this.$nextTick(()=>{
操作更新後DOM的程式碼。
});
2)、什麼是Vue.nextTick()
Vue.nextTick的程式碼思路示意
function nextTick(cb){
//DOM 更新
cb();
}
那麼,vue是如何知道DOM更新了?
-
MutationObserver:這是HTML5新增的API。用於監視DOM變動的介面,它可以監聽一個DOM物件上發生的子節點刪除、屬性修改、文字內容修改等
-
另外,考慮到,微任務比巨集任務耗時少,瀏覽器的相容性。所以,vue中延遲呼叫優先順序如下: Promise > MutationObserver > setImmediate > setTimeout
3)、應用場景:
在Vue生命週期的created()鉤子函式裡,如果要進行DOM操作,一定要把DOM操作放在Vue.nextTick()的回撥函式中。
在資料變化後要執行的某個操作,而這個操作需要使用隨資料改變而改變的DOM結構的時候,這個操作應該放在Vue.nextTick()的回撥函式中。
26、何時需要使用beforeDestroy?
總體來說,需要清除的是:當前元件不會自動銷燬的資料(不屬於當前元件的資料),並且該資料只是在當前元件裡使用。
1)、清除定時器(定時器是window物件的,不主動清除,是不會清除的)
2)、$on方法,那需要在元件銷燬前解綁。($on雖然屬於Vue的例項方法,但是,這個例項很有可能不是當前vue元件(如:事件匯流排中的用法))
3)、解除事件的繫結 scroll mousemove (這些事件是繫結在window物件或者document物件上的)
27、Vue中v-html會導致哪些問題
1)、可能會導致XSS攻擊。因為V-html更新的是元素的 innerHTML 。內容按普通 HTML 插入, 不會作為 Vue 模板進行編譯 。
2)、在單檔案元件裡,scoped 的樣式不會應用在 v-html 內部。因為那部分 HTML 沒有被 Vue 的模板編譯器處理。怎麼解決呢?如果你希望針對 v-html 的內容設定帶······作用域的 CSS,你可以替換為 CSS Modules 或用一個額外的全域性style元素手動設定類似 BEM 的作用域策略。
3)、後臺返回的html片段,以及css樣式和js,但是返回的js是不執行的,因為瀏覽器在渲染的時候並沒有將js渲染,這時要在$nextTick中動態建立script標籤並插入
28、為什麼v-for與v-if不能連用
應該說,建議不要連用,或者說,在迴圈時,通過if只能拿到少部分資料時,建議不要使用。
原因: v-for比v-if優先順序高,如果遍歷的陣列元素個數比較多,但是滿足v-if條件比較少的情況下。會浪費效能。而且,每次重新整理頁面時,都會執行這樣效能不高的程式碼。
解決:可以在computed裡迴圈陣列,通過filter的方式,過濾出需要的資料。而computed是有快取的,這樣可以節約記憶體
如下示例:
computed:{
isCompleteTask:function(){
return this.todos.filter(item=>item.isComplete);
}
}
29、如何自定義v-model
答: 使用vue元件中的選項model。
首先,官方元件裡可以使用v-model。而且,vue框架針對官方元件(文字框,單選鈕,複選框,下拉框)都有繫結的屬性和事件。如:文字框所繫結的屬性是value,繫結的事件是input。
那麼,自定義元件裡,如何使用v-model指令。就需要在vue元件裡增加model選項。
如下示例:
Vue.component('my-checkbox', {
props:['ccc','ddd'],//聲明瞭自定義元件的屬性。
model: {
prop: 'ccc', //表示v-model所繫結的屬性是 ccc
event: 'change'//表示v-model所繫結的事件是是 change
},
……………………
}