vue生命周期面試題
vue 生命周期是什么举塔?
Vue 實(shí)例從創(chuàng)建到銷毀的過程诺舔,就是生命周期
beforeCreate階段:vue實(shí)例的掛載元素el和數(shù)據(jù)對象data都是undefined,還沒有初始化卤唉。
created階段:vue實(shí)例的數(shù)據(jù)對象data有了涩惑,可以訪問里面的數(shù)據(jù)和方法,未掛載到DOM桑驱,el還沒有
beforeMount階段:vue實(shí)例的el和data都初始化了竭恬,但是掛載之前為虛擬的dom節(jié)點(diǎn)
mounted階段:vue實(shí)例掛載到真實(shí)DOM上,就可以通過DOM獲取DOM節(jié)點(diǎn)
beforeUpdate階段:響應(yīng)式數(shù)據(jù)更新時(shí)調(diào)用熬的,發(fā)生在虛擬DOM打補(bǔ)丁之前痊硕,適合在更新之前訪問現(xiàn)有的DOM,比如手動(dòng)移除已添加的事件監(jiān)聽器
updated階段:虛擬DOM重新渲染和打補(bǔ)丁之后調(diào)用押框,組成新的DOM已經(jīng)更新岔绸,避免在這個(gè)鉤子函數(shù)中操作數(shù)據(jù),防止死循環(huán)
beforeDestroy階段:實(shí)例銷毀前調(diào)用橡伞,實(shí)例還可以用盒揉,this能獲取到實(shí)例,常用于銷毀定時(shí)器兑徘,解綁事件
destroyed階段:實(shí)例銷毀后調(diào)用预烙,調(diào)用后所有事件監(jiān)聽器會(huì)被移除,所有的子實(shí)例都會(huì)被銷毀
vue生命周期的作用是什么道媚?
它的生命周期中有多個(gè)事件鉤子扁掸,讓我們在控制整個(gè)Vue實(shí)例的過程時(shí)更容易形成好的邏輯
每個(gè)生命周期適合哪些場景翘县?
生命周期鉤子的一些使用方法:
beforecreate : 可以在這加個(gè)loading事件,在加載實(shí)例時(shí)觸發(fā)
created : 初始化完成時(shí)的事件寫在這里谴分,如在這結(jié)束loading事件锈麸,異步請求也適宜在這里調(diào)用
mounted : 掛載元素,獲取到DOM節(jié)點(diǎn)
updated : 如果對數(shù)據(jù)統(tǒng)一處理牺蹄,在這里寫上相應(yīng)函數(shù)
beforeDestroy : 可以做一個(gè)確認(rèn)停止事件的確認(rèn)框
nextTick : 更新數(shù)據(jù)后立即操作dom
第一次頁面加載會(huì)觸發(fā)哪幾個(gè)鉤子忘伞?
第一次頁面加載時(shí)會(huì)觸發(fā) beforeCreate, created, beforeMount, mounted 這幾個(gè)鉤子
在beforeDestroy中我們都可以做那些事情
1.及時(shí)銷毀自定義事件,否則可能造成內(nèi)存泄露
2.解除綁定銷毀子組件以及事件監(jiān)聽器
何時(shí)需要使用beforeDestory?
1.解綁自定義事件event.$off
2.清除定時(shí)器
3.解綁自定義的dom事件沙兰,如window scroll 等
ajax請求應(yīng)該放在那個(gè)生命周期
mounted(整個(gè)渲染完成氓奈,dom加載完成)
js是單線程,ajax異步獲取數(shù)據(jù)
放在mounted 之前沒有用鼎天,只會(huì)讓邏輯更混亂
父子組件的生命周期觸發(fā)順序?
加載渲染過程:
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
子組件更新過程:
父beforeUpdate->子beforeUpdate->子updated->父updated
父組件更新過程:
父beforeUpdate->父updated
銷毀過程:
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
vue基本操作及原理面試題
v-show和v-if的區(qū)別?
v-show 是通過css 設(shè)置display控制顯示和隱藏
v-if是組件真正的渲染和銷毀舀奶,而不是顯示和隱藏
頻繁切換顯示狀態(tài)v-show,否則用v-if
Vue 中的 key 有什么作用斋射?Vue 中 key 的作用是:key 是為 Vue 中 vnode 的唯一標(biāo)記育勺,通過這個(gè) key,我們的 diff 操作可以更準(zhǔn)確罗岖、更快速 更準(zhǔn)確:因?yàn)閹?key 就不是就地復(fù)用了涧至,在 sameNode 函數(shù) a.key === b.key 對比中可以避免就地復(fù)用的情況。所以會(huì)更加準(zhǔn)確桑包。 更快速:利用 key 的唯一性生成 map 對象來獲取對應(yīng)節(jié)點(diǎn)南蓬,比遍歷方式更快
ref的作用
1.獲取dom元素 this.$refs.box
2.獲取子組件中的 datathis.$refs.box.msg
調(diào)用子組件中的方法 this.$refs.box.open()
computed 和 watch 的區(qū)別和運(yùn)用的場景?
computed: 是計(jì)算屬性哑了,依賴其它屬性值赘方,并且 computed 的值有緩存,只有它依賴的屬性值發(fā)生改變垒手,下一次獲取 computed 的值時(shí)才會(huì)重新計(jì)算 computed 的值;
watch: 更多的是「觀察」的作用倒信,類似于某些數(shù)據(jù)的監(jiān)聽回調(diào) 科贬,每當(dāng)監(jiān)聽的數(shù)據(jù)變化時(shí)都會(huì)執(zhí)行回調(diào)進(jìn)行后續(xù)操作;
運(yùn)用場景:
1.當(dāng)我們需要進(jìn)行數(shù)值計(jì)算鳖悠,并且依賴于其它數(shù)據(jù)時(shí)榜掌,應(yīng)該使用 computed,因?yàn)榭梢岳?computed 的緩存特性乘综,避免每次獲取值時(shí)憎账,都要重新計(jì)算;
2.當(dāng)我們需要在數(shù)據(jù)變化時(shí)執(zhí)行異步或開銷較大的操作時(shí)卡辰,應(yīng)該使用 watch胞皱,使用 watch 選項(xiàng)允許我們執(zhí)行異步操作 ( 訪問一個(gè) API )邪意,限制我們執(zhí)行該操作的頻率,并在我們得到最終結(jié)果前反砌,設(shè)置中間狀態(tài)雾鬼。這些都是計(jì)算屬性無法做到的。
如何將組件所有props傳遞給子組件宴树?
<user v-bind = "$props"/>
復(fù)制代碼
多個(gè)組件有相同的邏輯策菜,如何抽離?
mixin核心方法是 mergeOptions
可以幫助你合并數(shù)據(jù)酒贬,合并方法又憨,合并生命周期
雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理
1.vue 雙向數(shù)據(jù)綁定是通過 數(shù)據(jù)劫持 結(jié)合 發(fā)布訂閱模式的方式來實(shí)現(xiàn)的, 組件data的數(shù)據(jù)一旦變化锭吨,立刻觸發(fā)視圖的更新
2.核心 API - Object.defineProperty
Object.defineProperty缺點(diǎn):
1.深度監(jiān)聽蠢莺,需要遞歸到底,一次性計(jì)算量大
2.無法監(jiān)聽新增屬性/刪除屬性(vue2.0可以使用vue.set vue.delete)
3.無法原生監(jiān)聽數(shù)組耐齐,需要特殊處理
Proxy 的優(yōu)勢
Proxy 可以直接監(jiān)聽對象而非屬性
Proxy 可以直接監(jiān)聽數(shù)組的變化
Proxy 有多達(dá) 13 種攔截方法,不限于apply浪秘、ownKeys、deleteProperty埠况、has 等等是 Object.defineProperty 不具備的
Proxy 返回的是一個(gè)新對象,我們可以只操作新的對象達(dá)到目的,而 Object.defineProperty 只能遍歷對象屬性直接修改
Proxy 作為新標(biāo)準(zhǔn)將受到瀏覽器廠商重點(diǎn)持續(xù)的性能優(yōu)化耸携,也就是傳說中的新標(biāo)準(zhǔn)的性能紅利
為何組件data 必須是函數(shù)?
因?yàn)榻M件是可以復(fù)用的,JS 里對象是引用關(guān)系,如果組件 data 是一個(gè)對象,那么子組件中的 data 屬性值會(huì)互相污染,產(chǎn)生副作用辕翰。
所以一個(gè)組件的 data必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對象的獨(dú)立的拷貝夺衍。
new Vue 的實(shí)例是不會(huì)被復(fù)用的,因此不存在以上問題。
如何監(jiān)聽數(shù)組變化
1.重新定義原型
//重新定義數(shù)組的原型prototype
const oldArrayProperty=Array.prototype
//創(chuàng)建新對象喜命,原型指向oldArrayProperty沟沙,再擴(kuò)展新的方法不會(huì)影響原型
const arrProto=Object.create(oldArrayProperty)
復(fù)制代碼
2.重寫push pop等方法
3.proxy可以原生支持監(jiān)聽數(shù)組變化
何時(shí)使用異步組件?
加載大組件 路由異步加載
vue 為何是異步渲染壁榕,$nextTick何用矛紫?
vue 是組件級(jí)更新 為了防止每次修改數(shù)據(jù)都更新視圖,所以使用異步渲染
異步渲染(以及合并data修改)提高渲染性能
$nextTick在DOM更新完之后牌里,觸發(fā)回調(diào)
何時(shí)需要使用keep-alive?
緩存組件颊咬,不需要重復(fù)渲染
如多個(gè)靜態(tài)tab頁面切換,可以優(yōu)化性能
常用的2個(gè)屬性 include exclude
兩個(gè)生命周期 activated deactivated
LRU算法
vue 常見的性能優(yōu)化方式
合理使用v-show和v-if
合理使用computed 有緩存
v-for加key,以及避免和v-if同時(shí)使用
自定義事件牡辽,DOM 事件即時(shí)銷毀 (會(huì)導(dǎo)致內(nèi)存泄露)
合理使用異步組件
合理使用keep-alive
data層級(jí)不要太深喳篇,扁平化(深度監(jiān)聽時(shí)的一次性監(jiān)聽完成)
使用vue-loader 在開發(fā)環(huán)境做模板編譯(預(yù)編譯)
webpack 層級(jí)的優(yōu)化------
前端通用的性能優(yōu)化,如 圖片懶加載....
使用SSR
Vue 組件間通訊有哪幾種方式态辛?
props
/$emit
適用 父子組件通信 這種方法是 Vue 組件的基礎(chǔ)麸澜,相信大部分同學(xué)耳聞能詳,所以此處就不舉例展開介紹奏黑。ref
與$parent
/$children
適用 父子組件通信
ref
:如果在普通的 DOM 元素上使用炊邦,引用指向的就是 DOM 元素编矾;如果用在子組件上,引用就指向組件實(shí)例
$parent
/ $children
:訪問父 / 子實(shí)例
- EventBus (
$emit
/$on
) 適用于 父子铣耘、隔代洽沟、兄弟組件通信
這種方法通過一個(gè)空的 Vue 實(shí)例作為中央事件總線(事件中心),用它來觸發(fā)事件和監(jiān)聽事件蜗细,從而實(shí)現(xiàn)任何組件間的通信裆操,包括父子、隔代炉媒、兄弟組件 4. $attrs
/ $listeners
適用于 隔代組件通信
$attrs
:包含了父作用域中不被 prop 所識(shí)別 (且獲取) 的特性綁定 ( class 和 style 除外 )踪区。當(dāng)一個(gè)組件沒有聲明任何 prop 時(shí),這里會(huì)包含所有父作用域的綁定 ( class 和 style 除外 )吊骤,并且可以通過 v-bind=" $attrs
" 傳入內(nèi)部組件缎岗。通常配合 inheritAttrs 選項(xiàng)一起使用。
$listeners
:包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器白粉。它可以通過 v-on=" $listeners
" 傳入內(nèi)部組件
-
provide
/inject
適用于 隔代組件通信
祖先組件中通過 provider 來提供變量传泊,然后在子孫組件中通過 inject 來注入變量。
provide / inject API 主要解決了跨級(jí)組件間的通信問題鸭巴,不過它的使用場景眷细,主要是子組件獲取上級(jí)組件的狀態(tài),跨級(jí)組件間建立了一種主動(dòng)提供與依賴注入的關(guān)系鹃祖。
6.Vuex 適用于 父子溪椎、隔代、兄弟組件通信
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式恬口。每一個(gè) Vuex 應(yīng)用的核心就是 store(倉庫)校读。“store” 基本上就是一個(gè)容器祖能,它包含著你的應(yīng)用中大部分的狀態(tài) ( state )歉秫。
Vuex 的狀態(tài)存儲(chǔ)是響應(yīng)式的。當(dāng) Vue 組件從 store 中讀取狀態(tài)的時(shí)候养铸,若 store 中的狀態(tài)發(fā)生變化雁芙,那么相應(yīng)的組件也會(huì)相應(yīng)地得到高效更新。
改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation揭厚。這樣使得我們可以方便地跟蹤每一個(gè)狀態(tài)的變化却特。
vue3.0 有那些改進(jìn)扶供?
vue3采用TS來編寫
支持 composition API 解決了mixin的問題筛圆,讓代碼更有條理性
vue3 中的響應(yīng)式數(shù)據(jù)原理改成proxy
vdom的對比算法更新,只更新vdom的綁定來動(dòng)態(tài)數(shù)組部分
vuex 中action 和mutation 有何區(qū)別
mutaction 是同步更新數(shù)據(jù)(內(nèi)部會(huì)進(jìn)行是否為異步方式更新數(shù)據(jù)檢測) $watch 在嚴(yán)格模式下會(huì)報(bào)錯(cuò)
action 異步操作椿浓,可以獲取數(shù)據(jù)后調(diào)用mutaction 提交最終數(shù)據(jù)
vue-router 常見的路由模式太援?
hash 默認(rèn) h5 history (需要服務(wù)端支持)
實(shí)現(xiàn)的方式: hash onhashchange h5 history history.pushState
如何配置vue-router 異步加載闽晦?
在component 中配置 import
請用Vnode 描述一個(gè)DOM結(jié)構(gòu)
<div id="div1" calss="container">
<p>vdom</p>
<ul style="font-size:20px">
<li>a</li>
</ul>
</div>
//vnode
{
tag:'div',
props:{
className:'container',
id:'div1'
}
children:[
{
tag:'p',
children:'vdom'
},
{
tag:'ul',
props:{ style:'font-size :20px'},
children:[
{
tag:'li',
children:'a'
}
]
}
]
}
復(fù)制代碼
有想了解更多的小伙伴可以加Q群鏈接里面看一下,應(yīng)該對你們能夠有所幫助提岔。