vue实现多行数据提交_2020年大厂面试指南 Vue篇
點擊藍字 「前端小苑」關注我
導讀
vue的一些基礎知識,以及相關實現原理,一直是面試中比較熱門的題目,本文梳理了常見的Vue面試題。
注意:關于底層實現原理,建議最好還是參照源碼進行學習,有些原理相對比較復雜,很難通過一篇文章去深入理解,最終可能只是一知半解,面試時一深入提問,就露餡了。
本文主要是對Vue可能的面試點進行梳理,平時還是要注重知識的積累和儲備,才能游刃有余的應對工作和面試,部分題目會給出相關鏈接供詳細學習。
組件通信相關問題
1. 組件通信方式有哪些?
父子組件通信:
props?和?event、v-model、?.sync、?ref、?$parent?和?$children
非父子組件通信:
$attr?和?$listeners、?provide?和?inject、eventbus、通過根實例$root訪問、vuex、dispatch?和?brodcast
通信方式屬于較基礎的面試題,具體的可參考我的文章——?vue 組件通信看這篇就夠了
2. 子組件為什么不可以修改父組件傳遞的Prop?
Vue提倡單向數據流,即父級?props?的更新會流向子組件,但是反過來則不行。這是為了防止意外的改變父組件狀態,使得應用的數據流變得難以理解。如果破壞了單向數據流,當應用復雜時,debug 的成本會非常高。
3. v-model是如何實現雙向綁定的?
v-model?是用來在表單控件或者組件上創建雙向綁定的,他的本質是?v-bind?和?v-on?的語法糖,在一個組件上使用?v-model,默認會為組件綁定名為?value?的?prop?和名為?input?的事件。
文章——?vue 組件通信看這篇就夠了?中也有其詳細介紹
4. Vuex和單純的全局對象有什么區別?
Vuex和全局對象主要有兩大區別:
不能直接改變 store 中的狀態。改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地了解我們的應用。
5. 為什么 Vuex 的 mutation 中不能做異步操作?
Vuex中所有的狀態更新的唯一途徑都是mutation,異步操作通過 Action 來提交 mutation實現,這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地了解我們的應用。
每個mutation執行完成后都會對應到一個新的狀態變更,這樣devtools就可以打個快照存下來,然后就可以實現 time-travel 了。如果mutation支持異步操作,就沒有辦法知道狀態是何時更新的,無法很好的進行狀態的追蹤,給調試帶來困難。 參考尤大大回答:
https://www.zhihu.com/question/48759748/answer/112823337
聲明周期相關問題
1. vue組件有哪些聲明周期鉤子?
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。
?有自己獨立的鉤子函數 activated 和 deactivated。
2. Vue 的父組件和子組件生命周期鉤子執行順序是什么?
渲染過程:
父組件掛載完成一定是等子組件都掛載完成后,才算是父組件掛載完,所以父組件的mounted在子組件mouted之后。
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
子組件更新過程:
影響到父組件: 父beforeUpdate -> 子beforeUpdate->子updated -> 父updted
不影響父組件: 子beforeUpdate -> 子updated
父組件更新過程:
影響到子組件: 父beforeUpdate -> 子beforeUpdate->子updated -> 父updted
不影響子組件: 父beforeUpdate -> 父updated
銷毀過程:
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
看起來很多好像很難記憶,其實只要理解了,不管是哪種情況,都一定是父組件等待子組件完成后,才會執行自己對應完成的鉤子,就可以很容易記住。
相關屬性的作用 & 相似屬性對比
1. v-show 和 v-if 有哪些區別?
v-if?會在切換過程中對條件塊的事件監聽器和子組件進行銷毀和重建,如果初始條件是false,則什么都不做,直到條件第一次為true時才開始渲染模塊。
v-show?只是基于css進行切換,不管初始條件是什么,都會渲染。
所以,v-if?切換的開銷更大,而?v-show?初始化渲染開銷更大,在需要頻繁切換,或者切換的部分dom很復雜時,使用?v-show?更合適。渲染后很少切換的則使用?v-if?更合適。
2. computed 和 watch 有什么區別?
computed?計算屬性,是依賴其他屬性的計算值,并且有緩存,只有當依賴的值變化時才會更新。
watch?是在監聽的屬性發生變化時,在回調中執行一些邏輯。
所以,computed?適合在模板渲染中,某個值是依賴了其他的響應式對象甚至是計算屬性計算而來,而?watch?適合監聽某個值的變化去完成一段復雜的業務邏輯。
3. computed vs methods
計算屬性是基于他們的響應式依賴進行緩存的,只有在依賴發生變化時,才會計算求值,而使用?methods,每次都會執行相應的方法。
4. keep-alive 的作用是什么?
keep-alive?可以在組件切換時,保存其包裹的組件的狀態,使其不被銷毀,防止多次渲染。
其擁有兩個獨立的生命周期鉤子函數 actived 和 deactived,使用?keep-alive?包裹的組件在切換時不會被銷毀,而是緩存到內存中并執行 deactived 鉤子函數,命中緩存渲染后會執行 actived 鉤子函數。
5. Vue 中 v-html 會導致什么問題
在網站上動態渲染任意 HTML,很容易導致 XSS 攻擊。所以只能在可信內容上使用 v-html,且永遠不能用于用戶提交的內容上。
原理分析相關題目
這部分的面試題,只看答案部分是不夠的,最好結合源碼來分析,可以有更深的理解。我在之前的文章對某些源碼做過分析的,會給出鏈接。
1. Vue 的響應式原理
如果面試被問到這個問題,又描述不清楚,可以直接畫出 Vue 官方文檔的這個圖,對著圖來解釋效果會更好。
Vue 的響應式是通過?Object.defineProperty?對數據進行劫持,并結合觀察者模式實現。Vue 利用?Object.defineProperty?創建一個?observe?來劫持監聽所有的屬性,把這些屬性全部轉為?getter?和?setter。Vue 中每個組件實例都會對應一個?watcher?實例,它會在組件渲染的過程中把使用過的數據屬性通過?getter?收集為依賴。之后當依賴項的?setter?觸發時,會通知?watcher,從而使它關聯的組件重新渲染。
2. Object.defineProperty有哪些缺點?
這道題目也可以問成 “為什么vue3.0使用proxy實現響應式?” 其實都是對Object.defineProperty 和 proxy實現響應式的對比。
Object.defineProperty?只能劫持對象的屬性,而?Proxy?是直接代理對象由于?Object.defineProperty?只能對屬性進行劫持,需要遍歷對象的每個屬性。而?Proxy?可以直接代理對象。
Object.defineProperty?對新增屬性需要手動進行?Observe, 由于?Object.defineProperty?劫持的是對象的屬性,所以新增屬性時,需要重新遍歷對象,對其新增屬性再使用?Object.defineProperty?進行劫持。 也正是因為這個原因,使用 Vue 給?data?中的數組或對象新增屬性時,需要使用?vm.$set?才能保證新增的屬性也是響應式的。
Proxy?支持13種攔截操作,這是?defineProperty?所不具有的。
新標準性能紅利Proxy?作為新標準,長遠來看,JS引擎會繼續優化?Proxy?,但?getter?和?setter?基本不會再有針對性優化。
Proxy?兼容性差 目前并沒有一個完整支持?Proxy?所有攔截方法的Polyfill方案
更詳細的對比,可以查看我的文章?為什么Vue3.0不再使用defineProperty實現數據監聽?
3. Vue中如何檢測數組變化?
Vue 的?Observer?對數組做了單獨的處理,對數組的方法進行編譯,并賦值給數組屬性的?__proto__?屬性上,因為原型鏈的機制,找到對應的方法就不會繼續往上找了。編譯方法中會對一些會增加索引的方法(push,unshift,splice)進行手動 observe。具體同樣可以參考我的這篇文章?為什么Vue3.0不再使用defineProperty實現數據監聽?,里面有詳細的源碼分析。
4. 組件的 data 為什么要寫成函數形式?
Vue 的組件都是可復用的,一個組件創建好后,可以在多個地方復用,而不管復用多少次,組件內的?data?都應該是相互隔離,互不影響的,所以組件每復用一次,data?就應該復用一次,每一處復用組件的?data?改變應該對其他復用組件的數據不影響。
為了實現這樣的效果,data?就不能是單純的對象,而是以一個函數返回值的形式,所以每個組件實例可以維護獨立的數據拷貝,不會相互影響。
5. nextTick是做什么用的,其原理是什么?
能回答清楚這道問題的前提,是清楚 EventLoop 過程。
在下次 DOM 更新循環結束后執行延遲回調,在修改數據之后立即使用?nextTick?來獲取更新后的 DOM。
nextTick?對于 micro task 的實現,會先檢測是否支持?Promise,不支持的話,直接指向 macro task,而 macro task 的實現,優先檢測是否支持?setImmediate(高版本IE和Etage支持),不支持的再去檢測是否支持 MessageChannel,如果仍不支持,最終降級為?setTimeout?0;
默認的情況,會先以?micro task?方式執行,因為 micro task 可以在一次 tick 中全部執行完畢,在一些有重繪和動畫的場景有更好的性能。
但是由于 micro task 優先級較高,在某些情況下,可能會在事件冒泡過程中觸發,導致一些問題(可以參考 Vue 這個 issue:https://github.com/vuejs/vue/issues/6556),所以有些地方會強制使用 macro task (如?v-on)。
注意:之所以將?nextTick?的回調函數放入到數組中一次性執行,而不是直接在?nextTick?中執行回調函數,是為了保證在同一個tick內多次執行了?nextTcik,不會開啟多個異步任務,而是把這些異步任務都壓成一個同步任務,在下一個tick內執行完畢。
6. Vue 的模板編譯原理
vue模板的編譯過程分為3個階段:
第一步:解析
將模板字符串解析生成 AST,生成的AST 元素節點總共有 3 種類型,1 為普通元素, 2 為表達式,3為純文本。
第二步:優化語法樹
Vue 模板中并不是所有數據都是響應式的,有很多數據是首次渲染后就永遠不會變化的,那么這部分數據生成的 DOM 也不會變化,我們可以在 patch 的過程跳過對他們的比對。
此階段會深度遍歷生成的 AST 樹,檢測它的每一顆子樹是不是靜態節點,如果是靜態節點則它們生成 DOM 永遠不需要改變,這對運行時對模板的更新起到極大的優化作用。
第三步:生成代碼
const code = generate(ast, options)通過?generate?方法,將ast生成?render?函數。更多關于 AST,Vue 模板編譯原理,以及和 AST 相關的 Babel 工作原理等,我在?掌握了AST,再也不怕被問babel,vue編譯,Prettier等原理?中做了詳細介紹。
7. v-for 中 key 的作用是什么?
清晰回答這道問題,需要先清楚 Vue 的 diff 過程。關于 diff 原理,推薦一篇文章:?
?https://my.oschina.net/u/3060934/blog/3103711/print。
key?是給每個?vnode?指定的唯一?id,在同級的?vnode?diff 過程中,可以根據?key?快速的對比,來判斷是否為相同節點,并且利用?key?的唯一性可以生成?map?來更快的獲取相應的節點。
另外指定?key?后,就不再采用“就地復用”策略了,可以保證渲染的準確性。
8. 為什么 v-for 和 v-if 不建議用在一起
當?v-for?和?v-if?處于同一個節點時,v-for?的優先級比?v-if?更高,這意味著?v-if?將分別重復運行于每個?v-for?循環中。如果要遍歷的數組很大,而真正要展示的數據很少時,這將造成很大的性能浪費。
這種場景建議使用?computed,先對數據進行過濾。
路由相關問題
1. Vue-router 導航守衛有哪些
全局前置/鉤子:beforeEach、beforeResolve、afterEach
路由獨享的守衛:beforeEnter
組件內的守衛:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
完整的導航解析流程如下:
2. vue-router hash 模式和 history 模式有什么區別?
區別:
3. vue-router hash 模式和 history 模式是如何實現的?
hash 模式:
#后面 hash 值的變化,不會導致瀏覽器向服務器發出請求,瀏覽器不發出請求,就不會刷新頁面。同時通過監聽 hashchange 事件可以知道 hash 發生了哪些變化,然后根據 hash 變化來實現更新頁面部分內容的操作。
history 模式:
history 模式的實現,主要是 HTML5 標準發布的兩個 API,pushState?和?replaceState,這兩個 API 可以在改變 url,但是不會發送請求。這樣就可以監聽 url 變化來實現更新頁面部分內容的操作。
關于?vue-router?部分,推薦文章:
?https://juejin.im/post/5b10b46df265da6e2a08a724
本文是系列文章《2020年大廠面試指南》的第一篇文章,后續系列文章更新,請關注公眾號【前端小苑】。
更多文章請點擊“閱讀原文”喜歡本文點個“在看”喲!
總結
以上是生活随笔為你收集整理的vue实现多行数据提交_2020年大厂面试指南 Vue篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么彻底重装清空电脑_笔记本电脑怎么重装
- 下一篇: mybatisplus查询今天的数据_M