前端之路-VUE面試題

vue生命周期面試題
vue 生命周期是什么?

Vue 實(shí)例從創(chuàng)建到銷毀的過(guò)程,就是生命周期

beforeCreate階段:vue實(shí)例的掛載元素el和數(shù)據(jù)對(duì)象data都是undefined,還沒(méi)有初始化。

created階段:vue實(shí)例的數(shù)據(jù)對(duì)象data有了,可以訪問(wèn)里面的數(shù)據(jù)和方法,未掛載到DOM,el還沒(méi)有

beforeMount階段:vue實(shí)例的el和data都初始化了,但是掛載之前為虛擬的dom節(jié)點(diǎn)

mounted階段:vue實(shí)例掛載到真實(shí)DOM上,就可以通過(guò)DOM獲取DOM節(jié)點(diǎn)

beforeUpdate階段:響應(yīng)式數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬DOM打補(bǔ)丁之前,適合在更新之前訪問(wèn)現(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è)事件鉤子,讓我們?cè)诳刂普麄€(gè)Vue實(shí)例的過(guò)程時(shí)更容易形成好的邏輯

每個(gè)生命周期適合哪些場(chǎng)景?

生命周期鉤子的一些使用方法:

beforecreate : 可以在這加個(gè)loading事件,在加載實(shí)例時(shí)觸發(fā)

created : 初始化完成時(shí)的事件寫在這里,如在這結(jié)束loading事件,異步請(qǐng)求也適宜在這里調(diào)用

mounted : 掛載元素,獲取到DOM節(jié)點(diǎn)

updated : 如果對(duì)數(shù)據(jù)統(tǒng)一處理,在這里寫上相應(yīng)函數(shù)

beforeDestroy : 可以做一個(gè)確認(rèn)停止事件的確認(rèn)框

nextTick : 更新數(shù)據(jù)后立即操作dom

第一次頁(yè)面加載會(huì)觸發(fā)哪幾個(gè)鉤子?

第一次頁(yè)面加載時(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請(qǐng)求應(yīng)該放在那個(gè)生命周期

mounted(整個(gè)渲染完成,dom加載完成)

js是單線程,ajax異步獲取數(shù)據(jù)

放在mounted 之前沒(méi)有用,只會(huì)讓邏輯更混亂

父子組件的生命周期觸發(fā)順序?

加載渲染過(guò)程:

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子組件更新過(guò)程:

父beforeUpdate->子beforeUpdate->子updated->父updated

父組件更新過(guò)程:

父beforeUpdate->父updated

銷毀過(guò)程:

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

vue基本操作及原理面試題
v-show和v-if的區(qū)別?

v-show 是通過(guò)css 設(shè)置display控制顯示和隱藏

v-if是組件真正的渲染和銷毀,而不是顯示和隱藏

頻繁切換顯示狀態(tài)v-show,否則用v-if

Vue 中的 key 有什么作用?Vue 中 key 的作用是:key 是為 Vue 中 vnode 的唯一標(biāo)記,通過(guò)這個(gè) key,我們的 diff 操作可以更準(zhǔn)確、更快速 更準(zhǔn)確:因?yàn)閹?key 就不是就地復(fù)用了,在 sameNode 函數(shù) a.key === b.key 對(duì)比中可以避免就地復(fù)用的情況。所以會(huì)更加準(zhǔn)確。 更快速:利用 key 的唯一性生成 map 對(duì)象來(lái)獲取對(duì)應(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)用的場(chǎng)景?

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)用場(chǎng)景:

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í)行異步操作 ( 訪問(wèn)一個(gè) API ),限制我們執(zhí)行該操作的頻率,并在我們得到最終結(jié)果前,設(shè)置中間狀態(tài)。這些都是計(jì)算屬性無(wú)法做到的。

如何將組件所有props傳遞給子組件?

<user v-bind = "$props"/>
復(fù)制代碼

多個(gè)組件有相同的邏輯,如何抽離?

mixin核心方法是 mergeOptions

可以幫助你合并數(shù)據(jù),合并方法,合并生命周期

雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理

1.vue 雙向數(shù)據(jù)綁定是通過(guò) 數(shù)據(jù)劫持 結(jié)合 發(fā)布訂閱模式的方式來(lái)實(shí)現(xiàn)的, 組件data的數(shù)據(jù)一旦變化,立刻觸發(fā)視圖的更新

2.核心 API - Object.defineProperty

Object.defineProperty缺點(diǎn):

1.深度監(jiān)聽,需要遞歸到底,一次性計(jì)算量大

2.無(wú)法監(jiān)聽新增屬性/刪除屬性(vue2.0可以使用vue.set vue.delete)

3.無(wú)法原生監(jiān)聽數(shù)組,需要特殊處理

Proxy 的優(yōu)勢(shì)

Proxy 可以直接監(jiān)聽對(duì)象而非屬性

Proxy 可以直接監(jiān)聽數(shù)組的變化

Proxy 有多達(dá) 13 種攔截方法,不限于apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具備的

Proxy 返回的是一個(gè)新對(duì)象,我們可以只操作新的對(duì)象達(dá)到目的,而 Object.defineProperty 只能遍歷對(duì)象屬性直接修改

Proxy 作為新標(biāo)準(zhǔn)將受到瀏覽器廠商重點(diǎn)持續(xù)的性能優(yōu)化,也就是傳說(shuō)中的新標(biāo)準(zhǔn)的性能紅利

為何組件data 必須是函數(shù)?

因?yàn)榻M件是可以復(fù)用的,JS 里對(duì)象是引用關(guān)系,如果組件 data 是一個(gè)對(duì)象,那么子組件中的 data 屬性值會(huì)互相污染,產(chǎn)生副作用。

所以一個(gè)組件的 data必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝。

new Vue 的實(shí)例是不會(huì)被復(fù)用的,因此不存在以上問(wèn)題。

如何監(jiān)聽數(shù)組變化

1.重新定義原型

//重新定義數(shù)組的原型prototype
const oldArrayProperty=Array.prototype
//創(chuàng)建新對(duì)象,原型指向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è)面切換,可以優(yōu)化性能

常用的2個(gè)屬性 include exclude

兩個(gè)生命周期 activated deactivated

LRU算法

vue 常見(jiàn)的性能優(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 組件間通訊有哪幾種方式?

  1. props / $emit 適用 父子組件通信 這種方法是 Vue 組件的基礎(chǔ),相信大部分同學(xué)耳聞能詳,所以此處就不舉例展開介紹。

  2. ref$parent / $children 適用 父子組件通信

ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實(shí)例

$parent/ $children :訪問(wèn)父 / 子實(shí)例

  1. EventBus ( $emit / $on ) 適用于 父子、隔代、兄弟組件通信

這種方法通過(guò)一個(gè)空的 Vue 實(shí)例作為中央事件總線(事件中心),用它來(lái)觸發(fā)事件和監(jiān)聽事件,從而實(shí)現(xiàn)任何組件間的通信,包括父子、隔代、兄弟組件 4. $attrs / $listeners 適用于 隔代組件通信

$attrs :包含了父作用域中不被 prop 所識(shí)別 (且獲取) 的特性綁定 ( class 和 style 除外 )。當(dāng)一個(gè)組件沒(méi)有聲明任何 prop 時(shí),這里會(huì)包含所有父作用域的綁定 ( class 和 style 除外 ),并且可以通過(guò) v-bind=" $attrs " 傳入內(nèi)部組件。通常配合 inheritAttrs 選項(xiàng)一起使用。

$listeners :包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器。它可以通過(guò) v-on=" $listeners" 傳入內(nèi)部組件

  1. provide / inject 適用于 隔代組件通信
    祖先組件中通過(guò) provider 來(lái)提供變量,然后在子孫組件中通過(guò) inject 來(lái)注入變量。

provide / inject API 主要解決了跨級(jí)組件間的通信問(wèn)題,不過(guò)它的使用場(chǎng)景,主要是子組件獲取上級(jí)組件的狀態(tài),跨級(jí)組件間建立了一種主動(dòng)提供與依賴注入的關(guān)系。

6.Vuex 適用于 父子、隔代、兄弟組件通信

Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。每一個(gè) Vuex 應(yīng)用的核心就是 store(倉(cāng)庫(kù))?!皊tore” 基本上就是一個(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來(lái)編寫

支持 composition API 解決了mixin的問(wèn)題,讓代碼更有條理性

vue3 中的響應(yīng)式數(shù)據(jù)原理改成proxy

vdom的對(duì)比算法更新,只更新vdom的綁定來(lái)動(dòng)態(tài)數(shù)組部分

vuex 中action 和mutation 有何區(qū)別

mutaction 是同步更新數(shù)據(jù)(內(nèi)部會(huì)進(jìn)行是否為異步方式更新數(shù)據(jù)檢測(cè)) $watch 在嚴(yán)格模式下會(huì)報(bào)錯(cuò)

action 異步操作,可以獲取數(shù)據(jù)后調(diào)用mutaction 提交最終數(shù)據(jù)

vue-router 常見(jiàn)的路由模式?

hash 默認(rèn) h5 history (需要服務(wù)端支持)

實(shí)現(xiàn)的方式: hash onhashchange h5 history history.pushState

如何配置vue-router 異步加載?

在component 中配置 import

請(qǐng)用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)該對(duì)你們能夠有所幫助。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容