Vue 常見面試題總結
MVVM模型洽胶?
MVVM塔橡,是Model-View-ViewModel的簡寫,其本質是MVC模型的升級版启盛。其中Model代表數據模型蹦掐,View代表看到的頁面,ViewModel是View和Model之間的橋梁僵闯,數據會綁定到ViewModel層并自動將數據渲染到頁面中卧抗,視圖變化的時候會通知ViewModel層更新數據。以前是通過操作DOM來更新視圖鳖粟,現在是數據驅動視圖社裆。
Vue的生命周期
Vue 的生命周期可以分為8個階段:創(chuàng)建前后、掛載前后牺弹、更新前后浦马、銷毀前后,以及一些特殊場景的生命周期张漂。Vue 3 中還新增了是3個用于調試和服務端渲染的場景晶默。
Vue 2中的生命周期鉤子Vue 3選項式API的生命周期選項Vue 3 組合API中生命周期鉤子描述
beforeCreatebeforeCreatesetup()創(chuàng)建前,此時data和methods的數據都還沒有初始化
createdcreatedsetup()創(chuàng)建后航攒,data中有值磺陡,尚未掛載,可以進行一些Ajax請求
beforeMountbeforeMountonBeforeMount掛載前,會找到虛擬DOM币他,編譯成Render
mountedmountedonMounted掛載后坞靶,DOM已創(chuàng)建,可用于獲取訪問數據和DOM元素
beforeUpdatebeforeUpdateonBeforeUpdate更新前蝴悉,可用于獲取更新前各種狀態(tài)
updatedupdatedonUpdated更新后彰阴,所有狀態(tài)已是最新
beforeDestroybeforeUnmountonBeforeUnmount銷毀前,可用于一些定時器或訂閱的取消
destroyedunmountedonUnmounted銷毀后拍冠,可用于一些定時器或訂閱的取消
activatedactivatedonActivatedkeep-alive緩存的組件激活時
deactivateddeactivatedonDeactivatedkeep-alive緩存的組件停用時
errorCapturederrorCapturedonErrorCaptured捕獲一個來自子孫組件的錯誤時調用
—renderTrackedonRenderTracked調試鉤子尿这,響應式依賴被收集時調用
—renderTriggeredonRenderTriggered調試鉤子,響應式依賴被觸發(fā)時調用
—serverPrefetchonServerPrefetch組件實例在服務器上被渲染前調用
父子組件的生命周期:
加載渲染階段:父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
更新階段:父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
銷毀階段:父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
Vue.$nextTick
在下次 DOM 更新循環(huán)結束之后執(zhí)行延遲回調庆杜。在修改數據之后立即使用這個方法射众,獲取更新后的 DOM。
nextTick是 Vue 提供的一個全局 API晃财,由于 Vue 的異步更新策略叨橱,導致我們對數據修改后不會直接體現在 DOM 上,此時如果想要立即獲取更新后的 DOM 狀態(tài)断盛,就需要借助該方法罗洗。
Vue 在更新?DOM?時是異步執(zhí)行的。當數據發(fā)生變化郑临,Vue 將開啟一個異步更新隊列栖博,并緩沖在同一事件循環(huán)中發(fā)生的所有數據變更屑宠。如果同一個watcher被多次觸發(fā)厢洞,只會被推入隊列一次。這種在緩沖時去除重復數據對于避免不必要的計算和 DOM 操作是非常重要的典奉。nextTick方法會在隊列中加入一個回調函數躺翻,確保該函數在前面的 DOM 操作完成后才調用。
使用場景:
如果想要在修改數據后立刻得到更新后的DOM結構卫玖,可以使用Vue.nextTick()
在created生命周期中進行DOM操作
Vue 實例掛載過程中發(fā)生了什么公你?
掛載過程指的是app.mount()過程,這是一個初始化過程假瞬,整體上做了兩件事情:初始化和建立更新機制陕靠。
初始化會創(chuàng)建組件實例、初始化組件狀態(tài)脱茉、創(chuàng)建各種響應式數據剪芥。
建立更新機制這一步會立即執(zhí)行一次組件的更新函數,這會首次執(zhí)行組件渲染函數并執(zhí)行patch將vnode轉換為dom琴许; 同時首次執(zhí)行渲染函數會創(chuàng)建它內部響應式數據和組件更新函數之間的依賴關系税肪,這使得以后數據發(fā)生變化時會執(zhí)行對應的更新函數。
Vue 的模版編譯原理
Vue 中有個獨特的編譯器模塊,稱為compiler益兄,它的主要作用是將用戶編寫的template編譯為js中可執(zhí)行的render函數锻梳。
在Vue 中,編譯器會先對template進行解析净捅,這一步稱為parse疑枯,結束之后得到一個JS對象,稱之為抽象語法樹AST蛔六;然后是對AST進行深加工的轉換過程神汹,這一步稱為transform,最后將前面得到的AST生成JS代碼古今,也就是render函數屁魏。
Vue 的響應式原理
Vue 2 中的數據響應式會根據數據類型做不同的處理。如果是對象捉腥,則通過Object.defineProperty(obj,key,descriptor)攔截對象屬性訪問氓拼,當數據被訪問或改變時,感知并作出反應抵碟;如果是數組桃漾,則通過覆蓋數組原型的方法,擴展它的7個變更方法(push拟逮、pop撬统、shift、unshift敦迄、splice恋追、sort、reverse)罚屋,使這些方法可以額外的做更新通知苦囱,從而做出響應。
缺點:
初始化時的遞歸遍歷會造成性能損失脾猛;
通知更新過程需要維護大量dep實例和watcher實例撕彤,額外占用內存較多;
新增或刪除對象屬性無法攔截猛拴,需要通過Vue.set及delete這樣的 API 才能生效羹铅;
對于ES6中新產生的Map、Set這些數據結構不支持愉昆。
Vue 3 中利用ES6的Proxy機制代理需要響應化的數據职员。可以同時支持對象和數組撼唾,動態(tài)屬性增廉邑、刪都可以攔截哥蔚,新增數據結構均支持,對象嵌套屬性運行時遞歸蛛蒙,用到時才代理糙箍,也不需要維護特別多的依賴關系,性能取得很大進步牵祟。
虛擬DOM
概念:
虛擬DOM深夯,顧名思義就是虛擬的DOM對象,它本身就是一個JS對象诺苹,只不過是通過不同的屬性去描述一個視圖結構咕晋。
虛擬DOM的好處:
(1) 性能提升
直接操作DOM是有限制的,一個真實元素上有很多屬性收奔,如果直接對其進行操作掌呜,同時會對很多額外的屬性內容進行了操作,這是沒有必要的坪哄。如果將這些操作轉移到JS對象上质蕉,就會簡單很多。另外翩肌,操作DOM的代價是比較昂貴的模暗,頻繁的操作DOM容易引起頁面的重繪和回流。如果通過抽象VNode進行中間處理念祭,可以有效減少直接操作DOM次數兑宇,從而減少頁面的重繪和回流。
(2) 方便跨平臺實現
同一VNode節(jié)點可以渲染成不同平臺上對應的內容粱坤,比如:渲染在瀏覽器是DOM元素節(jié)點隶糕,渲染在Native(iOS、Android)變?yōu)閷目丶裙妗ue 3 中允許開發(fā)者基于VNode實現自定義渲染器(renderer)若厚,以便于針對不同平臺進行渲染。
結構:
沒有統(tǒng)一的標準蜒什,一般包括tag、props、children三項。
tag:必選抹沪。就是標簽忠售,也可以是組件,或者函數卓舵。
props:非必選。就是這個標簽上的屬性和方法。
children:非必選雕什。就是這個標簽的內容或者子節(jié)點。如果是文本節(jié)點就是字符串;如果有子節(jié)點就是數組贷岸。換句話說壹士,如果判斷children是字符串的話,就表示一定是文本節(jié)點偿警,這個節(jié)點肯定沒有子元素躏救。
diff 算法
概念:
diff算法是一種對比算法,通過對比舊的虛擬DOM和新的虛擬DOM螟蒸,得出是哪個虛擬節(jié)點發(fā)生了改變盒使,找出這個虛擬節(jié)點并只更新這個虛擬節(jié)點所對應的真實節(jié)點,而不用更新其他未發(fā)生改變的節(jié)點七嫌,實現精準地更新真實DOM少办,進而提高效率。
對比方式:
diff算法的整體策略是:深度優(yōu)先诵原,同層比較凡泣。比較只會在同層級進行, 不會跨層級比較;比較的過程中皮假,循環(huán)從兩邊向中間收攏鞋拟。
首先判斷兩個節(jié)點的tag是否相同,不同則刪除該節(jié)點重新創(chuàng)建節(jié)點進行替換惹资。
tag相同時贺纲,先替換屬性,然后對比子元素褪测,分為以下幾種情況:
新舊節(jié)點都有子元素時猴誊,采用雙指針方式進行對比。新舊頭尾指針進行比較侮措,循環(huán)向中間靠攏懈叹,根據情況調用patchVnode進行patch重復流程、調用createElem創(chuàng)建一個新節(jié)點分扎,從哈希表尋找key一致的VNode節(jié)點再分情況操作澄成。
新節(jié)點有子元素,舊節(jié)點沒有子元素畏吓,則將子元素虛擬節(jié)點轉化成真實節(jié)點插入即可墨状。
新節(jié)點沒有子元素,舊節(jié)點有子元素菲饼,則清空子元素肾砂,并設置為新節(jié)點的文本內容。
新舊節(jié)點都沒有子元素時宏悦,即都為文本節(jié)點镐确,則直接對比文本內容包吝,不同則更新。
Vue中key的作用源葫?
key的作用主要是為了更加高效的更新虛擬 DOM诗越。
Vue 判斷兩個節(jié)點是否相同時,主要是判斷兩者的key和元素類型tag臼氨。因此掺喻,如果不設置key,它的值就是 undefined储矩,則可能永遠認為這是兩個相同的節(jié)點感耙,只能去做更新操作,將造成大量的 DOM 更新操作持隧。
為什么組件中的 data 是一個函數即硼?
在 new Vue() 中,可以是函數也可以是對象屡拨,因為根實例只有一個只酥,不會產生數據污染。
在組件中呀狼,data 必須為函數裂允,目的是為了防止多個組件實例對象之間共用一個 data,產生數據污染哥艇;而采用函數的形式绝编,initData 時會將其作為工廠函數都會返回全新的 data 對象。
Vue 中組件間的通信方式貌踏?
父子組件通信:
父向子傳遞數據是通過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切換有一個局部編譯/卸載的過程冒黑,切換過程中合適的銷毀和重建內部的事件監(jiān)聽和子組件田绑;v-show只是簡單的基于 css 切換。
編譯條件不同抡爹。v-if是真正的條件渲染掩驱,它會確保在切換過程中條件塊內的事件監(jiā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較好默责,如:手風琴菜單,tab 頁簽等咸包;如果在運行時條件很少改變桃序,則使用v-if較好,如:用戶登錄之后烂瘫,根據權限不同來顯示不同的內容媒熊。
computed 和 watch 的區(qū)別?
computed計算屬性坟比,依賴其它屬性計算值芦鳍,內部任一依賴項的變化都會重新執(zhí)行該函數,計算屬性有緩存葛账,多次重復使用計算屬性時會從緩存中獲取返回值柠衅,計算屬性必須要有return關鍵詞。
watch偵聽到某一數據的變化從而觸發(fā)函數籍琳。當數據為對象類型時菲宴,對象中的屬性值變化時需要使用深度偵聽deep屬性贷祈,也可在頁面第一次加載時使用立即偵聽immdiate屬性。
運用場景:
計算屬性一般用在模板渲染中喝峦,某個值是依賴其它響應對象甚至是計算屬性而來势誊;而偵聽屬性適用于觀測某個值的變化去完成一段復雜的業(yè)務邏輯。
v-if 和 v-for 為什么不建議放在一起使用谣蠢?
Vue 2 中粟耻,v-for的優(yōu)先級比v-if高,這意味著v-if將分別重復運行于每一個v-for循環(huán)中眉踱。如果要遍歷的數組很大挤忙,而真正要展示的數據很少時,將造成很大的性能浪費勋锤。
Vue 3 中饭玲,則完全相反,v-if的優(yōu)先級高于v-for叁执,所以v-if執(zhí)行時茄厘,它調用的變量還不存在,會導致異常谈宛。
通常有兩種情況導致要這樣做:
為了過濾列表中的項目次哈,比如: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≈度幔可手動添加響應式數據共啃,解決數據變化視圖未更新問題。當在項目中直接設置數組的某一項的值暂题,或者直接設置對象的某個屬性值移剪,會發(fā)現頁面并沒有更新。這是因為Object.defineProperty()的限制薪者,監(jiān)聽不到數據變化纵苛,可通過this.$set(數組或對象,數組下標或對象的屬性名,更新后的值)解決赶站。
keep-alive 是什么幔虏?
作用:實現組件緩存纺念,保持組件的狀態(tài)贝椿,避免反復渲染導致的性能問題。
工作原理:Vue.js 內部將 DOM 節(jié)點陷谱,抽象成了一個個的 VNode 節(jié)點烙博,keep-alive組件的緩存也是基于 VNode 節(jié)點的。它將滿足條件的組件在 cache 對象中緩存起來烟逊,重新渲染的時候再將 VNode 節(jié)點從 cache 對象中取出并渲染渣窜。
可以設置以下屬性:
①include:字符串或正則,只有名稱匹配的組件會被緩存宪躯。
②exclude:字符串或正則乔宿,任何名稱匹配的組件都不會被緩存。
③max:數字访雪,最多可以緩存多少組件實例详瑞。
匹配首先檢查組件的name選項,如果name選項不可用臣缀,則匹配它的局部注冊名稱(父組件 components選項的鍵值)坝橡,匿名組件不能被匹配。
設置了keep-alive緩存的組件精置,會多出兩個生命周期鉤子:activated计寇、deactivated。
首次進入組件時:beforeCreate --> created --> beforeMount --> mounted --> activated --> beforeUpdate --> updated --> deactivated
再次進入組件時:activated --> beforeUpdate --> updated --> deactivated
mixin
mixin(混入)脂倦, 它提供了一種非常靈活的方式番宁,來分發(fā) Vue 組件中的可復用功能。
使用場景: 不同組件中經常會用到一些相同或相似的代碼赖阻,這些代碼的功能相對獨立蝶押。可以通過mixin 將相同或相似的代碼提出來政供。
缺點:
變量來源不明確
多 mixin 可能會造成命名沖突(解決方式:Vue 3的組合API)
mixin 和組件出現多對多的關系播聪,使項目復雜度變高。
插槽
slot插槽布隔,一般在組件內部使用离陶,封裝組件時,在組件內部不確定該位置是以何種形式的元素展示時衅檀,可以通過slot占據這個位置招刨,該位置的元素需要父組件以內容形式傳遞過來。slot分為:
默認插槽:子組件用<slot>標簽來確定渲染的位置哀军,標簽里面可以放DOM結構作為后備內容沉眶,當父組件在使用的時候打却,可以直接在子組件的標簽內寫入內容,該部分內容將插入子組件的<slot>標簽位置谎倔。如果父組件使用的時候沒有往插槽傳入內容柳击,后備內容就會顯示在頁面。
具名插槽:子組件用name屬性來表示插槽的名字片习,沒有指定name的插槽捌肴,會有隱含的名稱叫做default。父組件中在使用時在默認插槽的基礎上通過v-slot指令指定元素需要放在哪個插槽中藕咏,v-slot值為子組件插槽name屬性值状知。使用v-slot指令指定元素放在哪個插槽中,必須配合<template>元素孽查,且一個<template>元素只能對應一個預留的插槽饥悴,即不能多個<template>元素都使用v-slot指令指定相同的插槽。v-slot的簡寫是#盲再,例如v-slot:header可以簡寫為#header西设。
作用域插槽:子組件在<slot>標簽上綁定props數據,以將子組件數據傳給父組件使用洲胖。父組件獲取插槽綁定 props 數據的方法:
scope="接收的變量名":<template scope="接收的變量名">
slot-scope="接收的變量名":<template slot-scope="接收的變量名">
v-slot:插槽名="接收的變量名":<template v-slot:插槽名="接收的變量名">
Vue 中的修飾符有哪些济榨?
在Vue 中,修飾符處理了許多 DOM 事件的細節(jié)绿映,讓我們不再需要花大量的時間去處理這些煩惱的事情擒滑,而能有更多的精力專注于程序的邏輯處理。Vue中修飾符分為以下幾種:
表單修飾符
lazy填完信息叉弦,光標離開標簽的時候丐一,才會將值賦予給value,也就是在change事件之后再進行信息同步淹冰。
number自動將用戶輸入值轉化為數值類型库车,但如果這個值無法被parseFloat解析,則會返回原來的值樱拴。
trim自動過濾用戶輸入的首尾空格柠衍,而中間的空格不會被過濾。
事件修飾符
stop阻止了事件冒泡晶乔,相當于調用了event.stopPropagation方法珍坊。
prevent阻止了事件的默認行為,相當于調用了event.preventDefault方法正罢。
self只當在event.target是當前元素自身時觸發(fā)處理函數阵漏。
once綁定了事件以后只能觸發(fā)一次,第二次就不會觸發(fā)。
capture使用事件捕獲模式履怯,即元素自身觸發(fā)的事件先在此處處理回还,然后才交由內部元素進行處理。
passive告訴瀏覽器你不想阻止事件的默認行為叹洲。
native讓組件變成像html內置標簽那樣監(jiān)聽根元素的原生事件柠硕,否則組件上使用v-on只會監(jiān)聽自定義事件。
鼠標按鍵修飾符
left左鍵點擊疹味。
right右鍵點擊仅叫。
middle中鍵點擊。
鍵值修飾符
鍵盤修飾符是用來修飾鍵盤事件(onkeyup糙捺,onkeydown)的,有如下:keyCode存在很多笙隙,但vue為我們提供了別名洪灯,分為以下兩種:
普通鍵(enter、tab竟痰、delete签钩、space、esc坏快、up...)
系統(tǒng)修飾鍵(ctrl、alt莽鸿、meta昧旨、shift...)
對 SPA 的理解?
概念:
SPA(Single-page? application)祥得,即單頁面應用兔沃,它是一種網絡應用程序或網站的模型,通過動態(tài)重寫當前頁面來與用戶交互级及,這種方法避免了頁面之間切換時打斷用戶體驗乒疏。在SPA中,所有必要的代碼(HTML饮焦、JavaScript 和 CSS)都通過單個頁面的加載而檢索怕吴,或者根據需要(通常是響應用戶操作)動態(tài)裝載適當的資源并添加到頁面。頁面在任何時間點都不會重新加載县踢,也不會將控制轉移到其他頁面转绷。舉個例子,就像一個杯子殿雪,上午裝的是牛奶暇咆,中午裝的是咖啡,下午裝的是茶,變得始終是內容爸业,杯子始終不變其骄。
SPA與MPA的區(qū)別:
MPA(Muti-page application),即多頁面應用扯旷。在MPA中拯爽,每個頁面都是一個主頁面,都是獨立的钧忽,每當訪問一個頁面時毯炮,都需要重新加載 Html、CSS耸黑、JS 文件桃煎,公共文件則根據需求按需加載。
SPAMPA
組成一個主頁面和多個頁面片段多個主頁面
url模式hash模式history模式
SEO搜索引擎優(yōu)化難實現大刊,可使用SSR方式改善容易實現
數據傳遞容易通過url为迈、cookie、localStorage等傳遞
頁面切換速度快缺菌,用戶體驗良好切換加載資源葫辐,速度慢,用戶體驗差
維護成本相對容易相對復雜
SPA的優(yōu)缺點:
優(yōu)點:
具有桌面應用的即時性伴郁、網站的可移植性和可訪問性
用戶體驗好耿战、快,內容的改變不需要重新加載整個頁面
良好的前后端分離焊傅,分工更明確
缺點:
不利于搜索引擎的抓取
首次渲染速度相對較慢
雙向綁定剂陡?
概念:
Vue 中雙向綁定是一個指令v-model,可以綁定一個響應式數據到視圖租冠,同時視圖的變化能改變該值鹏倘。v-model是語法糖,默認情況下相當于:value和@input顽爹,使用v-model可以減少大量繁瑣的事件處理代碼纤泵,提高開發(fā)效率。
使用:
通常在表單項上使用v-model镜粤,還可以在自定義組件上使用捏题,表示某個值的輸入和輸出控制。
原理:
v-model是一個指令肉渴,雙向綁定實際上是Vue 的編譯器完成的公荧,通過輸出包含v-model模版的組件渲染函數,實際上還是value屬性的綁定及input事件監(jiān)聽同规,事件回調函數中會做相應變量的更新操作循狰。
子組件是否可以直接改變父組件的數據窟社?
所有的prop都遵循著單項綁定原則,props因父組件的更新而變化绪钥,自然地將新狀態(tài)向下流往子組件灿里,而不會逆向傳遞。這避免了子組件意外修改父組件的狀態(tài)的情況程腹,不然應用的數據流將很容易變得混亂而難以理解匣吊。
另外,每次父組件更新后寸潦,所有的子組件中的props都會被更新為最新值色鸳,這就意味著不應該子組件中去修改一個prop,若這么做了见转,Vue 會在控制臺上拋出警告命雀。
實際開發(fā)過程中通常有兩個場景導致要修改prop:
prop被用于傳入初始值,而子組件想在之后將其作為一個局部數據屬性池户。這種情況下咏雌,最好是新定義一個局部數據屬性,從props獲取初始值即可校焦。
需要對傳入的prop值做進一步轉換。最好是基于該prop值定義一個計算屬性统倒。
實踐中寨典,如果確實要更改父組件屬性,應emit一個事件讓父組件變更房匆。當對象或數組作為props被傳入時耸成,雖然子組件無法更改props綁定,但仍然可以更改對象或數組內部的值浴鸿。這是因為JS的對象和數組是按引用傳遞井氢,而對于 Vue 來說,禁止這樣的改動雖然可能岳链,但是有很大的性能損耗花竞,比較得不償失。
Vue Router中的常用路由模式和原理掸哑?
hash 模式:
location.hash的值就是url中 # 后面的東西约急。它的特點在于:hash雖然出現url中,但不會被包含在HTTP請求中苗分,對后端完全沒有影響厌蔽,因此改變hash不會重新加載頁面。
可以為hash的改變添加監(jiān)聽事件window.addEventListener("hashchange", funcRef, false)摔癣,每一次改變hash (window.location.hash)奴饮,都會在瀏覽器的訪問歷史中增加一個記錄纬向,利用hash的以上特點,就可以實現前端路由更新視圖但不重新請求頁面的功能了戴卜。
特點:兼容性好但是不美觀
history 模式:
利用 HTML5 History Interface 中新增的pushState()和replaceState()方法逾条。
這兩個方法應用于瀏覽器的歷史記錄棧,在當前已有的back叉瘩、forward膳帕、go的基礎上,他們提供了對歷史記錄進行修改的功能薇缅。
這兩個方法有個共同點:當調用他們修改瀏覽器歷史記錄棧后危彩,雖然當前url改變了,但瀏覽器不會刷新頁面泳桦,這就為單頁面應用前端路由“更新視圖但不重新請求頁面”提供了基礎
特點:雖然美觀汤徽,但是刷新會出現 404 需要后端進行配置。
動態(tài)路由灸撰?
很多時候谒府,我們需要將給定匹配模式的路由映射到同一個組件,這種情況就需要定義動態(tài)路由浮毯。例如完疫,我們有一個 User組件,對于所有 ID 各不相同的用戶债蓝,都要使用這個組件來渲染壳鹤。那么,我們可以在 vue-router 的路由路徑中使用動態(tài)路徑參數(dynamic segment)來達到這個效果:{path: '/user/:id', compenent: User}饰迹,其中:id就是動態(tài)路徑參數芳誓。
對Vuex的理解?
概念:
Vuex 是 Vue 專用的狀態(tài)管理庫啊鸭,它以全局方式集中管理應用的狀態(tài)锹淌,并以相應的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化。
解決的問題:
Vuex 主要解決的問題是多組件之間狀態(tài)共享赠制。利用各種通信方式赂摆,雖然也能夠實現狀態(tài)共享,但是往往需要在多個組件之間保持狀態(tài)的一致性憎妙,這種模式很容易出問題库正,也會使程序邏輯變得復雜。Vuex 通過把組件的共享狀態(tài)抽取出來厘唾,以全局單例模式管理褥符,這樣任何組件都能用一致的方式獲取和修改狀態(tài),響應式的數據也能夠保證簡潔的單向流動抚垃,使代碼變得更具結構化且易于維護喷楣。
什么時候用:
Vuex 并非是必須的趟大,它能夠管理狀態(tài),但同時也帶來更多的概念和框架铣焊。如果我們不打算開發(fā)大型單頁應用或應用里沒有大量全局的狀態(tài)需要維護逊朽,完全沒有使用Vuex的必要,一個簡單的 store 模式就夠了曲伊。反之叽讳,Vuex將是自然而然的選擇。
用法:
Vuex 將全局狀態(tài)放入state對象中坟募,它本身是一顆狀態(tài)樹岛蚤,組件中使用store實例的state訪問這些狀態(tài);然后用配套的mutation方法修改這些狀態(tài)懈糯,并且只能用mutation修改狀態(tài)涤妒,在組件中調用commit方法提交mutation;如果應用中有異步操作或復雜邏輯組合赚哗,需要編寫action她紫,執(zhí)行結束如果有狀態(tài)修改仍需提交mutation,組件中通過dispatch派發(fā)action屿储。最后是模塊化贿讹,通過modules選項組織拆分出去的各個子模塊,在訪問狀態(tài)(state)時需注意添加子模塊的名稱够掠,如果子模塊有設置namespace围详,那么提交mutation和派發(fā)action時還需要額外的命名空間前綴。
頁面刷新后Vuex 狀態(tài)丟失怎么解決祖屏?
Vuex 只是在內存中保存狀態(tài),刷新后就會丟失买羞,如果要持久化就需要保存起來袁勺。
localStorage就很合適,提交mutation的時候同時存入localStorage畜普,在store中把值取出來作為state的初始值即可期丰。
也可以使用第三方插件,推薦使用vuex-persist插件吃挑,它是為 Vuex 持久化儲存而生的一個插件钝荡,不需要你手動存取storage,而是直接將狀態(tài)保存至cookie或者localStorage中舶衬。
關于 Vue SSR 的理解埠通?
SSR即服務端渲染(Server Side Render),就是將 Vue 在客戶端把標簽渲染成 html 的工作放在服務端完成逛犹,然后再把 html 直接返回給客戶端端辱。
優(yōu)點:
有著更好的 SEO梁剔,并且首屏加載速度更快。
缺點:
開發(fā)條件會受限制舞蔽,服務器端渲染只支持 beforeCreate 和 created 兩個鉤子荣病,當我們需要一些外部擴展庫時需要特殊處理,服務端渲染應用程序也需要處于 Node.js 的運行環(huán)境渗柿。服務器會有更大的負載需求个盆。
了解哪些 Vue 的性能優(yōu)化方法?
路由懶加載朵栖。有效拆分應用大小颊亮,訪問時才異步加載。
keep-alive緩存頁面混槐。避免重復創(chuàng)建組件實例编兄,且能保留緩存組件狀態(tài)。
v-for遍歷避免同時使用v-if声登。實際上在 Vue 3 中已經是一個錯誤用法了狠鸳。
長列表性能優(yōu)化,可采用虛擬列表悯嗓。
v-once件舵。不再變化的數據使用v-once。
事件銷毀脯厨。組件銷毀后把全局變量和定時器銷毀铅祸。
圖片懶加載。
第三方插件按需引入合武。
子組件分割临梗。較重的狀態(tài)組件適合拆分。
服務端渲染稼跳。