最常考的 30 個 Vue 面試題總結(jié)?。?!

Vue 常見面試題總結(jié)

MVVM模型?

MVVM,是Model-View-ViewModel的簡寫,其本質(zhì)是MVC模型的升級版。其中 Model 代表數(shù)據(jù)模型,View 代表看到的頁面,ViewModel是View和Model之間的橋梁,數(shù)據(jù)會綁定到ViewModel層并自動將數(shù)據(jù)渲染到頁面中,視圖變化的時候會通知ViewModel層更新數(shù)據(jù)。以前是通過操作DOM來更新視圖,現(xiàn)在是數(shù)據(jù)驅(qū)動視圖。


Vue的生命周期

Vue 的生命周期可以分為8個階段:創(chuàng)建前后、掛載前后、更新前后、銷毀前后,以及一些特殊場景的生命周期。Vue 3 中還新增了是3個用于調(diào)試和服務(wù)端渲染的場景。


Vue 2中的生命周期鉤子 Vue 3選項式API的生命周期選項 Vue 3 組合API中生命周期鉤子 描述

beforeCreate beforeCreate setup() 創(chuàng)建前,此時data和 methods的數(shù)據(jù)都還沒有初始化

created created setup() 創(chuàng)建后,data中有值,尚未掛載,可以進行一些Ajax請求

beforeMount beforeMount onBeforeMount 掛載前,會找到虛擬DOM,編譯成Render

mounted mounted onMounted 掛載后,DOM已創(chuàng)建,可用于獲取訪問數(shù)據(jù)和DOM元素

beforeUpdate beforeUpdate onBeforeUpdate 更新前,可用于獲取更新前各種狀態(tài)

updated updated onUpdated 更新后,所有狀態(tài)已是最新

beforeDestroy beforeUnmount onBeforeUnmount 銷毀前,可用于一些定時器或訂閱的取消

destroyed unmounted onUnmounted 銷毀后,可用于一些定時器或訂閱的取消

activated activated onActivated keep-alive緩存的組件激活時

deactivated deactivated onDeactivated keep-alive緩存的組件停用時

errorCaptured errorCaptured onErrorCaptured 捕獲一個來自子孫組件的錯誤時調(diào)用

renderTracked onRenderTracked 調(diào)試鉤子,響應(yīng)式依賴被收集時調(diào)用

renderTriggered onRenderTriggered 調(diào)試鉤子,響應(yīng)式依賴被觸發(fā)時調(diào)用

serverPrefetch onServerPrefetch 組件實例在服務(wù)器上被渲染前調(diào)用

「父子組件的生命周期:」


加載渲染階段:父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

更新階段:父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

銷毀階段:父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

Vue.$nextTick

「在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新后的 DOM?!?/p>


nextTick 是 Vue 提供的一個全局 API,由于 Vue 的異步更新策略,導(dǎo)致我們對數(shù)據(jù)修改后不會直接體現(xiàn)在 DOM 上,此時如果想要立即獲取更新后的 DOM 狀態(tài),就需要借助該方法。


Vue 在更新 DOM 時是異步執(zhí)行的。當(dāng)數(shù)據(jù)發(fā)生變化,Vue 將開啟一個異步更新隊列,并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)變更。如果同一個 watcher 被多次觸發(fā),只會被推入隊列一次。這種在緩沖時去除重復(fù)數(shù)據(jù)對于避免不必要的計算和 DOM 操作是非常重要的。nextTick方法會在隊列中加入一個回調(diào)函數(shù),確保該函數(shù)在前面的 DOM 操作完成后才調(diào)用。


使用場景:


如果想要在修改數(shù)據(jù)后立刻得到更新后的DOM結(jié)構(gòu),可以使用Vue.nextTick()

在created生命周期中進行DOM操作

Vue 實例掛載過程中發(fā)生了什么?

掛載過程指的是 app.mount()過程,這是一個初始化過程,整體上做了兩件事情:初始化和建立更新機制。


初始化會創(chuàng)建組件實例、初始化組件狀態(tài)、創(chuàng)建各種響應(yīng)式數(shù)據(jù)。


建立更新機制這一步會立即執(zhí)行一次組件的更新函數(shù),這會首次執(zhí)行組件渲染函數(shù)并執(zhí)行patch將vnode 轉(zhuǎn)換為 dom;同時首次執(zhí)行渲染函數(shù)會創(chuàng)建它內(nèi)部響應(yīng)式數(shù)據(jù)和組件更新函數(shù)之間的依賴關(guān)系,這使得以后數(shù)據(jù)發(fā)生變化時會執(zhí)行對應(yīng)的更新函數(shù)。


Vue 的模版編譯原理

Vue 中有個獨特的編譯器模塊,稱為compiler,它的主要作用是將用戶編寫的template編譯為js中可執(zhí)行的render函數(shù)。

在Vue 中,編譯器會先對template進行解析,這一步稱為parse,結(jié)束之后得到一個JS對象,稱之為抽象語法樹AST;然后是對AST進行深加工的轉(zhuǎn)換過程,這一步稱為transform,最后將前面得到的AST生成JS代碼,也就是render函數(shù)。


Vue 的響應(yīng)式原理

Vue 2 中的數(shù)據(jù)響應(yīng)式會根據(jù)數(shù)據(jù)類型做不同的處理。如果是對象,則通過Object.defineProperty(obj,key,descriptor)攔截對象屬性訪問,當(dāng)數(shù)據(jù)被訪問或改變時,感知并作出反應(yīng);如果是數(shù)組,則通過覆蓋數(shù)組原型的方法,擴展它的7個變更方法(push、pop、shift、unshift、splice、sort、reverse),使這些方法可以額外的做更新通知,從而做出響應(yīng)。

缺點:

初始化時的遞歸遍歷會造成性能損失;

通知更新過程需要維護大量 dep 實例和 watcher 實例,額外占用內(nèi)存較多;

新增或刪除對象屬性無法攔截,需要通過 Vue.set 及 delete 這樣的 API 才能生效;

對于ES6中新產(chǎn)生的Map、Set這些數(shù)據(jù)結(jié)構(gòu)不支持。

Vue 3 中利用ES6的Proxy機制代理需要響應(yīng)化的數(shù)據(jù)??梢酝瑫r支持對象和數(shù)組,動態(tài)屬性增、刪都可以攔截,新增數(shù)據(jù)結(jié)構(gòu)均支持,對象嵌套屬性運行時遞歸,用到時才代理,也不需要維護特別多的依賴關(guān)系,性能取得很大進步。

虛擬DOM

概念:

虛擬DOM,顧名思義就是虛擬的DOM對象,它本身就是一個JS對象,只不過是通過不同的屬性去描述一個視圖結(jié)構(gòu)。

虛擬DOM的好處:

(1) 性能提升

直接操作DOM是有限制的,一個真實元素上有很多屬性,如果直接對其進行操作,同時會對很多額外的屬性內(nèi)容進行了操作,這是沒有必要的。如果將這些操作轉(zhuǎn)移到JS對象上,就會簡單很多。另外,操作DOM的代價是比較昂貴的,頻繁的操作DOM容易引起頁面的重繪和回流。如果通過抽象VNode進行中間處理,可以有效減少直接操作DOM次數(shù),從而減少頁面的重繪和回流。

(2) 方便跨平臺實現(xiàn)

同一VNode節(jié)點可以渲染成不同平臺上對應(yīng)的內(nèi)容,比如:渲染在瀏覽器是DOM元素節(jié)點,渲染在Native(iOS、Android)變?yōu)閷?yīng)的控件。Vue 3 中允許開發(fā)者基于VNode實現(xiàn)自定義渲染器(renderer),以便于針對不同平臺進行渲染。

結(jié)構(gòu):

沒有統(tǒng)一的標(biāo)準(zhǔn),一般包括tag、props、children三項。

tag:必選。就是標(biāo)簽,也可以是組件,或者函數(shù)。

props:非必選。就是這個標(biāo)簽上的屬性和方法。

children:非必選。就是這個標(biāo)簽的內(nèi)容或者子節(jié)點。如果是文本節(jié)點就是字符串;如果有子節(jié)點就是數(shù)組。換句話說,如果判斷children是字符串的話,就表示一定是文本節(jié)點,這個節(jié)點肯定沒有子元素。

diff 算法

概念:

diff算法是一種對比算法,通過對比舊的虛擬DOM和新的虛擬DOM,得出是哪個虛擬節(jié)點發(fā)生了改變,找出這個虛擬節(jié)點并只更新這個虛擬節(jié)點所對應(yīng)的真實節(jié)點,而不用更新其他未發(fā)生改變的節(jié)點,實現(xiàn)精準(zhǔn)地更新真實DOM,進而提高效率。

對比方式:

diff算法的整體策略是:深度優(yōu)先,同層比較。比較只會在同層級進行, 不會跨層級比較;比較的過程中,循環(huán)從兩邊向中間收攏。

首先判斷兩個節(jié)點的tag是否相同,不同則刪除該節(jié)點重新創(chuàng)建節(jié)點進行替換。

tag相同時,先替換屬性,然后對比子元素,分為以下幾種情況:

新舊節(jié)點都有子元素時,采用雙指針方式進行對比。新舊頭尾指針進行比較,循環(huán)向中間靠攏,根據(jù)情況調(diào)用patchVnode進行patch重復(fù)流程、調(diào)用createElem創(chuàng)建一個新節(jié)點,從哈希表尋找 key一致的VNode節(jié)點再分情況操作。

新節(jié)點有子元素,舊節(jié)點沒有子元素,則將子元素虛擬節(jié)點轉(zhuǎn)化成真實節(jié)點插入即可。

新節(jié)點沒有子元素,舊節(jié)點有子元素,則清空子元素,并設(shè)置為新節(jié)點的文本內(nèi)容。

新舊節(jié)點都沒有子元素時,即都為文本節(jié)點,則直接對比文本內(nèi)容,不同則更新。

Vue中key的作用?

key的作用主要是為了更加高效的更新虛擬 DOM。


Vue 判斷兩個節(jié)點是否相同時,主要是判斷兩者的key和元素類型tag。因此,如果不設(shè)置key ,它的值就是 undefined,則可能永遠認為這是兩個相同的節(jié)點,只能去做更新操作,將造成大量的 DOM 更新操作。


為什么組件中的 data 是一個函數(shù)?

在 new Vue() 中,可以是函數(shù)也可以是對象,因為根實例只有一個,不會產(chǎn)生數(shù)據(jù)污染。


在組件中,data 必須為函數(shù),目的是為了防止多個組件實例對象之間共用一個 data,產(chǎn)生數(shù)據(jù)污染;而采用函數(shù)的形式,initData 時會將其作為工廠函數(shù)都會返回全新的 data 對象。


Vue 中組件間的通信方式?

父子組件通信:父向子傳遞數(shù)據(jù)是通過props,子向父是通過$emit觸發(fā)事件;通過父鏈/子鏈也可以通信($parent/$children);ref也可以訪問組件實例;provide/inject;$attrs/$listeners。

兄弟組件通信:全局事件總線EventBus、Vuex。

跨層級組件通信:全局事件總線EventBus、Vuex、provide/inject。

v-show 和 v-if 的區(qū)別?

控制手段不同。v-show是通過給元素添加 css 屬性display: none,但元素仍然存在;而v-if控制元素顯示或隱藏是將元素整個添加或刪除。

編譯過程不同。v-if切換有一個局部編譯/卸載的過程,切換過程中合適的銷毀和重建內(nèi)部的事件監(jiān)聽和子組件;v-show只是簡單的基于 css 切換。

編譯條件不同。v-if是真正的條件渲染,它會確保在切換過程中條件塊內(nèi)的事件監(jiān)聽器和子組件適當(dāng)?shù)乇讳N毀和重建,渲染條件為假時,并不做操作,直到為真才渲染。

觸發(fā)生命周期不同。v-show由 false 變?yōu)?true 的時候不會觸發(fā)組件的生命周期;v-if由 false 變?yōu)?true 的時候,觸發(fā)組件的beforeCreate、created、beforeMount、mounted鉤子,由 true 變?yōu)?false 的時候觸發(fā)組件的beforeDestory、destoryed鉤子。

性能消耗不同。v-if有更高的切換消耗;v-show有更高的初始渲染消耗。

使用場景:

如果需要非常頻繁地切換,則使用v-show較好,如:手風(fēng)琴菜單,tab 頁簽等;如果在運行時條件很少改變,則使用v-if較好,如:用戶登錄之后,根據(jù)權(quán)限不同來顯示不同的內(nèi)容。


computed 和 watch 的區(qū)別?

computed計算屬性,依賴其它屬性計算值,內(nèi)部任一依賴項的變化都會重新執(zhí)行該函數(shù),計算屬性有緩存,多次重復(fù)使用計算屬性時會從緩存中獲取返回值,計算屬性必須要有return關(guān)鍵詞。

watch偵聽到某一數(shù)據(jù)的變化從而觸發(fā)函數(shù)。當(dāng)數(shù)據(jù)為對象類型時,對象中的屬性值變化時需要使用深度偵聽deep屬性,也可在頁面第一次加載時使用立即偵聽immdiate屬性。

運用場景:

計算屬性一般用在模板渲染中,某個值是依賴其它響應(yīng)對象甚至是計算屬性而來;而偵聽屬性適用于觀測某個值的變化去完成一段復(fù)雜的業(yè)務(wù)邏輯。








v-if 和 v-for 為什么不建議放在一起使用?

Vue 2 中,v-for的優(yōu)先級比v-if高,這意味著v-if將分別重復(fù)運行于每一個v-for循環(huán)中。如果要遍歷的數(shù)組很大,而真正要展示的數(shù)據(jù)很少時,將造成很大的性能浪費。


Vue 3 中,則完全相反,v-if的優(yōu)先級高于v-for,所以v-if執(zhí)行時,它調(diào)用的變量還不存在,會導(dǎo)致異常。


通常有兩種情況導(dǎo)致要這樣做:


為了過濾列表中的項目,比如:v-for = "user in users" v-if = "user.active"。這種情況,可以定義一個計算屬性,讓其返回過濾后的列表即可。

為了避免渲染本該被隱藏的列表,比如v-for = "user in users" v-if = "showUsersFlag"。這種情況,可以將v-if移至容器元素上或在外面包一層template即可。

Vue 2中的set方法?

set是Vue 2中的一個全局API。可手動添加響應(yīng)式數(shù)據(jù),解決數(shù)據(jù)變化視圖未更新問題。當(dāng)在項目中直接設(shè)置數(shù)組的某一項的值,或者直接設(shè)置對象的某個屬性值,會發(fā)現(xiàn)頁面并沒有更新。這是因為Object.defineProperty()的限制,監(jiān)聽不到數(shù)據(jù)變化,可通過this.$set(數(shù)組或?qū)ο?,?shù)組下標(biāo)或?qū)ο蟮膶傩悦?,更新后的?解決。


keep-alive 是什么?

作用:實現(xiàn)組件緩存,保持組件的狀態(tài),避免反復(fù)渲染導(dǎo)致的性能問題。

工作原理:Vue.js 內(nèi)部將 DOM 節(jié)點,抽象成了一個個的 VNode 節(jié)點,keep-alive組件的緩存也是基于 VNode 節(jié)點的。它將滿足條件的組件在 cache 對象中緩存起來,重新渲染的時候再將 VNode 節(jié)點從 cache 對象中取出并渲染。

可以設(shè)置以下屬性:

① include:字符串或正則,只有名稱匹配的組件會被緩存。

② exclude:字符串或正則,任何名稱匹配的組件都不會被緩存。

③ max:數(shù)字,最多可以緩存多少組件實例。

匹配首先檢查組件的name選項,如果name選項不可用,則匹配它的局部注冊名稱(父組件 components選項的鍵值),匿名組件不能被匹配。

設(shè)置了keep-alive緩存的組件,會多出兩個生命周期鉤子:activated、deactivated。

首次進入組件時:beforeCreate --> created --> beforeMount --> mounted --> activated --> beforeUpdate --> updated --> deactivated

再次進入組件時:activated --> beforeUpdate --> updated --> deactivated


mixin

mixin(混入), 它提供了一種非常靈活的方式,來分發(fā) Vue 組件中的可復(fù)用功能。


使用場景:不同組件中經(jīng)常會用到一些相同或相似的代碼,這些代碼的功能相對獨立??梢酝ㄟ^mixin 將相同或相似的代碼提出來。


缺點:


變量來源不明確

多 mixin 可能會造成命名沖突(解決方式:Vue 3的組合API)

mixin 和組件出現(xiàn)多對多的關(guān)系,使項目復(fù)雜度變高。

插槽

slot插槽,一般在組件內(nèi)部使用,封裝組件時,在組件內(nèi)部不確定該位置是以何種形式的元素展示時,可以通過slot占據(jù)這個位置,該位置的元素需要父組件以內(nèi)容形式傳遞過來。slot分為:


默認插槽:子組件用<slot>標(biāo)簽來確定渲染的位置,標(biāo)簽里面可以放DOM結(jié)構(gòu)作為后備內(nèi)容,當(dāng)父組件在使用的時候,可以直接在子組件的標(biāo)簽內(nèi)寫入內(nèi)容,該部分內(nèi)容將插入子組件的<slot>標(biāo)簽位置。如果父組件使用的時候沒有往插槽傳入內(nèi)容,后備內(nèi)容就會顯示在頁面。

具名插槽:子組件用name屬性來表示插槽的名字,沒有指定name的插槽,會有隱含的名稱叫做 default。父組件中在使用時在默認插槽的基礎(chǔ)上通過v-slot指令指定元素需要放在哪個插槽中,v-slot值為子組件插槽name屬性值。使用v-slot指令指定元素放在哪個插槽中,必須配合<template>元素,且一個<template>元素只能對應(yīng)一個預(yù)留的插槽,即不能多個<template> 元素都使用v-slot指令指定相同的插槽。v-slot的簡寫是#,例如v-slot:header可以簡寫為#header。

作用域插槽:子組件在<slot>標(biāo)簽上綁定props數(shù)據(jù),以將子組件數(shù)據(jù)傳給父組件使用。父組件獲取插槽綁定 props 數(shù)據(jù)的方法:

scope="接收的變量名":<template scope="接收的變量名">

slot-scope="接收的變量名":<template slot-scope="接收的變量名">

v-slot:插槽名="接收的變量名":<template v-slot:插槽名="接收的變量名">

Vue 中的修飾符有哪些?

在Vue 中,修飾符處理了許多 DOM 事件的細節(jié),讓我們不再需要花大量的時間去處理這些煩惱的事情,而能有更多的精力專注于程序的邏輯處理。Vue中修飾符分為以下幾種:


表單修飾符

lazy 填完信息,光標(biāo)離開標(biāo)簽的時候,才會將值賦予給value,也就是在change事件之后再進行信息同步。

number 自動將用戶輸入值轉(zhuǎn)化為數(shù)值類型,但如果這個值無法被parseFloat解析,則會返回原來的值。

trim 自動過濾用戶輸入的首尾空格,而中間的空格不會被過濾。

事件修飾符

stop 阻止了事件冒泡,相當(dāng)于調(diào)用了event.stopPropagation方法。

prevent 阻止了事件的默認行為,相當(dāng)于調(diào)用了event.preventDefault方法。

self 只當(dāng)在 event.target 是當(dāng)前元素自身時觸發(fā)處理函數(shù)。

once 綁定了事件以后只能觸發(fā)一次,第二次就不會觸發(fā)。

capture 使用事件捕獲模式,即元素自身觸發(fā)的事件先在此處處理,然后才交由內(nèi)部元素進行處理。

passive 告訴瀏覽器你不想阻止事件的默認行為。

native 讓組件變成像html內(nèi)置標(biāo)簽?zāi)菢颖O(jiān)聽根元素的原生事件,否則組件上使用 v-on 只會監(jiān)聽自定義事件。

鼠標(biāo)按鍵修飾符

left 左鍵點擊。

right 右鍵點擊。

middle 中鍵點擊。

鍵值修飾符

鍵盤修飾符是用來修飾鍵盤事件(onkeyup,onkeydown)的,有如下:keyCode存在很多,但vue為我們提供了別名,分為以下兩種:

普通鍵(enter、tab、delete、space、esc、up...)

系統(tǒng)修飾鍵(ctrl、alt、meta、shift...)

對 SPA 的理解?

概念:

SPA(Single-page application),即單頁面應(yīng)用,它是一種網(wǎng)絡(luò)應(yīng)用程序或網(wǎng)站的模型,通過動態(tài)重寫當(dāng)前頁面來與用戶交互,這種方法避免了頁面之間切換時打斷用戶體驗。在SPA中,所有必要的代碼(HTML、JavaScript 和 CSS)都通過單個頁面的加載而檢索,或者根據(jù)需要(通常是響應(yīng)用戶操作)動態(tài)裝載適當(dāng)?shù)馁Y源并添加到頁面。頁面在任何時間點都不會重新加載,也不會將控制轉(zhuǎn)移到其他頁面。舉個例子,就像一個杯子,上午裝的是牛奶,中午裝的是咖啡,下午裝的是茶,變得始終是內(nèi)容,杯子始終不變。

SPA與MPA的區(qū)別:

MPA(Muti-page application),即多頁面應(yīng)用。在MPA中,每個頁面都是一個主頁面,都是獨立的,每當(dāng)訪問一個頁面時,都需要重新加載 Html、CSS、JS 文件,公共文件則根據(jù)需求按需加載。

SPAMPA組成一個主頁面和多個頁面片段多個主頁面url模式hash模式history模式SEO搜索引擎優(yōu)化難實現(xiàn),可使用SSR方式改善容易實現(xiàn)數(shù)據(jù)傳遞容易通過url、cookie、localStorage等傳遞頁面切換速度快,用戶體驗良好切換加載資源,速度慢,用戶體驗差維護成本相對容易相對復(fù)雜

3.SPA的優(yōu)缺點:


缺點:

    不利于搜索引擎的抓取


    首次渲染速度相對較慢


優(yōu)點:

    具有桌面應(yīng)用的即時性、網(wǎng)站的可移植性和可訪問性


    用戶體驗好、快,內(nèi)容的改變不需要重新加載整個頁面


    良好的前后端分離,分工更明確


雙向綁定?

概念:

Vue 中雙向綁定是一個指令v-model,可以綁定一個響應(yīng)式數(shù)據(jù)到視圖,同時視圖的變化能改變該值。v-model是語法糖,默認情況下相當(dāng)于:value和@input,使用v-model可以減少大量繁瑣的事件處理代碼,提高開發(fā)效率。

使用:

通常在表單項上使用v-model,還可以在自定義組件上使用,表示某個值的輸入和輸出控制。

原理:

v-model是一個指令,雙向綁定實際上是Vue 的編譯器完成的,通過輸出包含v-model模版的組件渲染函數(shù),實際上還是value屬性的綁定及input事件監(jiān)聽,事件回調(diào)函數(shù)中會做相應(yīng)變量的更新操作。

子組件是否可以直接改變父組件的數(shù)據(jù)?

所有的prop都遵循著單項綁定原則,props因父組件的更新而變化,自然地將新狀態(tài)向下流往子組件,而不會逆向傳遞。這避免了子組件意外修改父組件的狀態(tài)的情況,不然應(yīng)用的數(shù)據(jù)流將很容易變得混亂而難以理解。

另外,每次父組件更新后,所有的子組件中的props都會被更新為最新值,這就意味著不應(yīng)該子組件中去修改一個prop,若這么做了,Vue 會在控制臺上拋出警告。

實際開發(fā)過程中通常有兩個場景導(dǎo)致要修改prop:

prop被用于傳入初始值,而子組件想在之后將其作為一個局部數(shù)據(jù)屬性。這種情況下,最好是新定義一個局部數(shù)據(jù)屬性,從props獲取初始值即可。

需要對傳入的prop值做進一步轉(zhuǎn)換。最好是基于該prop值定義一個計算屬性。

實踐中,如果確實要更改父組件屬性,應(yīng)emit一個事件讓父組件變更。當(dāng)對象或數(shù)組作為props被傳入時,雖然子組件無法更改props綁定,但仍然「可以」更改對象或數(shù)組內(nèi)部的值。這是因為JS的對象和數(shù)組是按引用傳遞,而對于 Vue 來說,禁止這樣的改動雖然可能,但是有很大的性能損耗,比較得不償失。

Vue Router中的常用路由模式和原理?

hash 模式:

location.hash的值就是url中 # 后面的東西。它的特點在于:hash雖然出現(xiàn)url中,但不會被包含在HTTP請求中,對后端完全沒有影響,因此改變hash不會重新加載頁面。

可以為hash的改變添加監(jiān)聽事件window.addEventListener("hashchange", funcRef, false),每一次改變hash (window.location.hash),都會在瀏覽器的訪問歷史中增加一個記錄,利用hash的以上特點,就可以實現(xiàn)「前端路由更新視圖但不重新請求頁面」的功能了。

特點:兼容性好但是不美觀

history 模式:

利用 HTML5 History Interface 中新增的pushState()和replaceState()方法。

這兩個方法應(yīng)用于瀏覽器的歷史記錄棧,在當(dāng)前已有的back、forward、go 的基礎(chǔ)上,他們提供了對歷史記錄進行修改的功能。

這兩個方法有個共同點:當(dāng)調(diào)用他們修改瀏覽器歷史記錄棧后,雖然當(dāng)前url改變了,但瀏覽器不會刷新頁面,這就為單頁面應(yīng)用前端路由“更新視圖但不重新請求頁面”提供了基礎(chǔ)

特點:雖然美觀,但是刷新會出現(xiàn) 404 需要后端進行配置。


動態(tài)路由?

很多時候,我們需要將給定匹配模式的路由映射到同一個組件,這種情況就需要定義動態(tài)路由。例如,我們有一個 User組件,對于所有 ID 各不相同的用戶,都要使用這個組件來渲染。那么,我們可以在 vue-router 的路由路徑中使用動態(tài)路徑參數(shù)(dynamic segment)來達到這個效果:{path: '/user/:id', compenent: User},其中:id就是動態(tài)路徑參數(shù)。


對Vuex的理解?

概念:

Vuex 是 Vue 專用的狀態(tài)管理庫,它以全局方式集中管理應(yīng)用的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。

解決的問題:

Vuex 主要解決的問題是多組件之間狀態(tài)共享。利用各種通信方式,雖然也能夠?qū)崿F(xiàn)狀態(tài)共享,但是往往需要在多個組件之間保持狀態(tài)的一致性,這種模式很容易出問題,也會使程序邏輯變得復(fù)雜。Vuex 通過把組件的共享狀態(tài)抽取出來,以全局單例模式管理,這樣任何組件都能用一致的方式獲取和修改狀態(tài),響應(yīng)式的數(shù)據(jù)也能夠保證簡潔的單向流動,使代碼變得更具結(jié)構(gòu)化且易于維護。

什么時候用:

Vuex 并非是必須的,它能夠管理狀態(tài),但同時也帶來更多的概念和框架。如果我們不打算開發(fā)大型單頁應(yīng)用或應(yīng)用里沒有大量全局的狀態(tài)需要維護,完全沒有使用Vuex的必要,一個簡單的 store 模式就夠了。反之,Vuex將是自然而然的選擇。

用法:

Vuex 將全局狀態(tài)放入state對象中,它本身是一顆狀態(tài)樹,組件中使用store實例的state訪問這些狀態(tài);然后用配套的mutation方法修改這些狀態(tài),并且只能用mutation修改狀態(tài),在組件中調(diào)用commit方法提交mutation;如果應(yīng)用中有異步操作或復(fù)雜邏輯組合,需要編寫action,執(zhí)行結(jié)束如果有狀態(tài)修改仍需提交mutation,組件中通過dispatch派發(fā)action。最后是模塊化,通過modules選項組織拆分出去的各個子模塊,在訪問狀態(tài)(state)時需注意添加子模塊的名稱,如果子模塊有設(shè)置namespace,那么提交mutation和派發(fā)action時還需要額外的命名空間前綴。

頁面刷新后Vuex 狀態(tài)丟失怎么解決?

Vuex 只是在內(nèi)存中保存狀態(tài),刷新后就會丟失,如果要持久化就需要保存起來。


localStorage就很合適,提交mutation的時候同時存入localStorage,在store中把值取出來作為state的初始值即可。


也可以使用第三方插件,推薦使用vuex-persist插件,它是為 Vuex 持久化儲存而生的一個插件,不需要你手動存取storage,而是直接將狀態(tài)保存至 cookie 或者 localStorage中。


關(guān)于 Vue SSR 的理解?

SSR即服務(wù)端渲染(Server Side Render),就是將 Vue 在客戶端把標(biāo)簽渲染成 html 的工作放在服務(wù)端完成,然后再把 html 直接返回給客戶端。


優(yōu)點:

有著更好的 SEO,并且首屏加載速度更快。

缺點:

開發(fā)條件會受限制,服務(wù)器端渲染只支持 beforeCreate 和 created 兩個鉤子,當(dāng)我們需要一些外部擴展庫時需要特殊處理,服務(wù)端渲染應(yīng)用程序也需要處于 Node.js 的運行環(huán)境。服務(wù)器會有更大的負載需求。

了解哪些 Vue 的性能優(yōu)化方法?

路由懶加載。有效拆分應(yīng)用大小,訪問時才異步加載。

keep-alive緩存頁面。避免重復(fù)創(chuàng)建組件實例,且能保留緩存組件狀態(tài)。

v-for遍歷避免同時使用v-if。實際上在 Vue 3 中已經(jīng)是一個錯誤用法了。

長列表性能優(yōu)化,可采用虛擬列表。

v-once。不再變化的數(shù)據(jù)使用v-once。

事件銷毀。組件銷毀后把全局變量和定時器銷毀。

圖片懶加載。

第三方插件按需引入。

子組件分割。較重的狀態(tài)組件適合拆分。

服務(wù)端渲染。






作者:前端開發(fā)愛好者


歡迎關(guān)注微信公眾號 :前端開發(fā)愛好者


添加好友備注【進階學(xué)習(xí)】拉你進技術(shù)交流群