這篇文章主要介紹“常見Vue面試題及答案有哪些”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“常見Vue面試題及答案有哪些”文章能幫助大家解決問題。
站在用戶的角度思考問題,與客戶深入溝通,找到岳麓網(wǎng)站設(shè)計與岳麓網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名申請、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋岳麓地區(qū)。
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 組件實例在創(chuàng)建后都會經(jīng)過一系列的初始化過程,這個過程中會運行叫做生命周期鉤子的函數(shù),以便于用戶在特定的階段有機會添加自己的代碼。
Vue 的生命周期可以分為8個階段:創(chuàng)建前后、掛載前后、更新前后、銷毀前后,以及一些特殊場景的生命周期。Vue 3 中還新增了是3個用于調(diào)試和服務(wù)端渲染的場景?!鞠嚓P(guān)推薦:vuejs視頻教程、web前端開發(fā)】
Vue 2中的生命周期 | Vue 3中的生命周期 | 描述 |
---|---|---|
beforeCreate | beforeCreate | 創(chuàng)建前,此時data 和 methods 的數(shù)據(jù)都還沒有初始化 |
created | created | 創(chuàng)建后,data 中有值,尚未掛載,可以進行一些Ajax 請求 |
beforeMount | beforeMount | 掛載前,會找到虛擬DOM ,編譯成Render |
mounted | mounted | 掛載后,DOM 已創(chuàng)建,可用于獲取訪問數(shù)據(jù)和DOM 元素 |
beforeUpdate | beforeUpdate | 更新前,可用于獲取更新前各種狀態(tài) |
updated | updated | 更新后,所有狀態(tài)已是最新 |
beforeDestroy | beforeUnmount | 銷毀前,可用于一些定時器或訂閱的取消 |
destroyed | unmounted | 銷毀后,可用于一些定時器或訂閱的取消 |
activated | activated | keep-alive 緩存的組件激活時 |
deactivated | deactivated | keep-alive 緩存的組件停用時 |
errorCaptured | errorCaptured | 捕獲一個來自子孫組件的錯誤時調(diào)用 |
— | renderTracked | 調(diào)試鉤子,響應(yīng)式依賴被收集時調(diào)用 |
— | renderTriggered | 調(diào)試鉤子,響應(yīng)式依賴被觸發(fā)時調(diào)用 |
— | serverPrefetch | 組件實例在服務(wù)器上被渲染前調(diào)用 |
父子組件的生命周期:
加載渲染階段
:父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
更新階段
:父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
銷毀階段
:父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新后的 DOM。
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
操作
掛載過程指的是 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 中有個獨特的編譯器模塊,稱為compiler
,它的主要作用是將用戶編寫的template
編譯為js中可執(zhí)行的render
函數(shù)。
在Vue 中,編譯器會先對template
進行解析,這一步稱為parse
,結(jié)束之后得到一個JS對象,稱之為抽象語法樹AST
;然后是對AST
進行深加工的轉(zhuǎn)換過程,這一步稱為transform
,最后將前面得到的AST
生成JS代碼,也就是render
函數(shù)。
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對象,它本身就是一個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é)點肯定沒有子元素。
1、概念:
diff
算法是一種對比算法,通過對比舊的虛擬DOM和新的虛擬DOM,得出是哪個虛擬節(jié)點發(fā)生了改變,找出這個虛擬節(jié)點并只更新這個虛擬節(jié)點所對應(yīng)的真實節(jié)點,而不用更新其他未發(fā)生改變的節(jié)點,實現(xiàn)精準(zhǔn)地更新真實DOM,進而提高效率。
2、對比方式:
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)容,不同則更新。
key
的作用主要是為了更加高效的更新虛擬 DOM
。
Vue 判斷兩個節(jié)點是否相同時,主要是判斷兩者的key
和元素類型tag
。因此,如果不設(shè)置key
,它的值就是 undefined,則可能永遠(yuǎn)認(rèn)為這是兩個相同的節(jié)點,只能去做更新操作,將造成大量的 DOM 更新操作。
在 new Vue() 中,可以是函數(shù)也可以是對象,因為根實例只有一個,不會產(chǎn)生數(shù)據(jù)污染。
在組件中,data 必須為函數(shù),目的是為了防止多個組件實例對象之間共用一個 data,產(chǎn)生數(shù)據(jù)污染;而采用函數(shù)的形式,initData 時會將其作為工廠函數(shù)都會返回全新的 data 對象。
父子組件通信:
父向子傳遞數(shù)據(jù)是通過props
,子向父是通過$emit
觸發(fā)事件;通過父鏈/子鏈也可以通信($parent
/$children
);ref
也可以訪問組件實例;provide
/inject
;$attrs
/$listeners
。
兄弟組件通信:
全局事件總線EventBus
、Vuex
。
跨層級組件通信:
全局事件總線EventBus
、Vuex
、provide
/inject
。
控制手段不同。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
計算屬性,依賴其它屬性計算值,內(nèi)部任一依賴項的變化都會重新執(zhí)行該函數(shù),計算屬性有緩存,多次重復(fù)使用計算屬性時會從緩存中獲取返回值,計算屬性必須要有return
關(guān)鍵詞。
watch
偵聽到某一數(shù)據(jù)的變化從而觸發(fā)函數(shù)。當(dāng)數(shù)據(jù)為對象類型時,對象中的屬性值變化時需要使用深度偵聽deep
屬性,也可在頁面第一次加載時使用立即偵聽immdiate
屬性。
運用場景:
計算屬性一般用在模板渲染中,某個值是依賴其它響應(yīng)對象甚至是計算屬性而來;而偵聽屬性適用于觀測某個值的變化去完成一段復(fù)雜的業(yè)務(wù)邏輯。
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
即可。
可手動添加響應(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ū)ο蟮膶傩悦?,更新后的?
解決。
作用:實現(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
(混入), 它提供了一種非常靈活的方式,來分發(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
分為:
默認(rèn)插槽
:子組件用
標(biāo)簽來確定渲染的位置,標(biāo)簽里面可以放DOM
結(jié)構(gòu)作為后備內(nèi)容,當(dāng)父組件在使用的時候,可以直接在子組件的標(biāo)簽內(nèi)寫入內(nèi)容,該部分內(nèi)容將插入子組件的
標(biāo)簽位置。如果父組件使用的時候沒有往插槽傳入內(nèi)容,后備內(nèi)容就會顯示在頁面。
具名插槽
:子組件用name
屬性來表示插槽的名字,沒有指定name
的插槽,會有隱含的名稱叫做 default
。父組件中在使用時在默認(rèn)插槽的基礎(chǔ)上通過v-slot
指令指定元素需要放在哪個插槽中,v-slot
值為子組件插槽name
屬性值。使用v-slot
指令指定元素放在哪個插槽中,必須配合元素,且一個
元素只能對應(yīng)一個預(yù)留的插槽,即不能多個
元素都使用
v-slot
指令指定相同的插槽。v-slot
的簡寫是#
,例如v-slot:header
可以簡寫為#header
。
作用域插槽
:子組件在
標(biāo)簽上綁定props
數(shù)據(jù),以將子組件數(shù)據(jù)傳給父組件使用。父組件獲取插槽綁定 props 數(shù)據(jù)的方法:
scope="接收的變量名":
slot-scope="接收的變量名":
v-slot:插槽名="接收的變量名":
在Vue 中,修飾符處理了許多 DOM 事件的細(xì)節(jié),讓我們不再需要花大量的時間去處理這些煩惱的事情,而能有更多的精力專注于程序的邏輯處理。Vue中修飾符分為以下幾種:
表單修飾符lazy
填完信息,光標(biāo)離開標(biāo)簽的時候,才會將值賦予給value,也就是在change
事件之后再進行信息同步。number
自動將用戶輸入值轉(zhuǎn)化為數(shù)值類型,但如果這個值無法被parseFloat
解析,則會返回原來的值。trim
自動過濾用戶輸入的首尾空格,而中間的空格不會被過濾。
事件修飾符stop
阻止了事件冒泡,相當(dāng)于調(diào)用了event.stopPropagation
方法。prevent
阻止了事件的默認(rèn)行為,相當(dāng)于調(diào)用了event.preventDefault
方法。self
只當(dāng)在 event.target
是當(dāng)前元素自身時觸發(fā)處理函數(shù)。once
綁定了事件以后只能觸發(fā)一次,第二次就不會觸發(fā)。capture
使用事件捕獲模式,即元素自身觸發(fā)的事件先在此處處理,然后才交由內(nèi)部元素進行處理。passive
告訴瀏覽器你不想阻止事件的默認(rèn)行為。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(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ù)需求按需加載。
SPA | MPA | |
---|---|---|
組成 | 一個主頁面和多個頁面片段 | 多個主頁面 |
url模式 | hash模式 | history模式 |
SEO搜索引擎優(yōu)化 | 難實現(xiàn),可使用SSR方式改善 | 容易實現(xiàn) |
數(shù)據(jù)傳遞 | 容易 | 通過url、cookie、localStorage等傳遞 |
頁面切換 | 速度快,用戶體驗良好 | 切換加載資源,速度慢,用戶體驗差 |
維護成本 | 相對容易 | 相對復(fù)雜 |
SPA
的優(yōu)缺點:
優(yōu)點:
缺點:
不利于搜索引擎的抓取
首次渲染速度相對較慢
具有桌面應(yīng)用的即時性、網(wǎng)站的可移植性和可訪問性
用戶體驗好、快,內(nèi)容的改變不需要重新加載整個頁面
良好的前后端分離,分工更明確
概念:
Vue 中雙向綁定是一個指令v-model
,可以綁定一個響應(yīng)式數(shù)據(jù)到視圖,同時視圖的變化能改變該值。v-model
是語法糖,默認(rèn)情況下相當(dāng)于:value
和@input
,使用v-model
可以減少大量繁瑣的事件處理代碼,提高開發(fā)效率。
使用:
通常在表單項上使用v-model
,還可以在自定義組件上使用,表示某個值的輸入和輸出控制。
原理:v-model
是一個指令,雙向綁定實際上是Vue 的編譯器完成的,通過輸出包含v-model
模版的組件渲染函數(shù),實際上還是value
屬性的綁定及input
事件監(jiān)聽,事件回調(diào)函數(shù)中會做相應(yīng)變量的更新操作。
所有的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 來說,禁止這樣的改動雖然可能,但是有很大的性能損耗,比較得不償失。
1、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)前端路由更新視圖但不重新請求頁面的功能了。
特點:兼容性好但是不美觀
2、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)路由。例如,我們有一個 User組件,對于所有 ID 各不相同的用戶,都要使用這個組件來渲染。那么,我們可以在 vue-router 的路由路徑中使用動態(tài)路徑參數(shù)(dynamic segment)
來達(dá)到這個效果:{path: '/user/:id', compenent: User}
,其中:id
就是動態(tài)路徑參數(shù)。
概念:
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 只是在內(nèi)存中保存狀態(tài),刷新后就會丟失,如果要持久化就需要保存起來。
localStorage
就很合適,提交mutation
的時候同時存入localStorage
,在store
中把值取出來作為state
的初始值即可。
也可以使用第三方插件,推薦使用vuex-persist
插件,它是為 Vuex 持久化儲存而生的一個插件,不需要你手動存取storage
,而是直接將狀態(tài)保存至 cookie
或者 localStorage
中。
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ù)器會有更大的負(fù)載需求。
路由懶加載。有效拆分應(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ù)端渲染。
關(guān)于“常見Vue面試題及答案有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。