2025年vue高頻面試題(附答案)_第1頁
2025年vue高頻面試題(附答案)_第2頁
2025年vue高頻面試題(附答案)_第3頁
2025年vue高頻面試題(附答案)_第4頁
2025年vue高頻面試題(附答案)_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

2025年vue高頻面試題(附答案)Vue3響應式系統(tǒng)中,Ref和Reactive的核心區(qū)別是什么?如何正確使用它們?Ref通過包裹原始值(如string、number)或?qū)ο髞韯?chuàng)建響應式數(shù)據(jù),其內(nèi)部通過`RefImpl`類實現(xiàn),暴露`value`屬性來訪問和修改值。當值為對象時,Ref會自動調(diào)用`reactive`使其深層響應。Reactive則直接基于Proxy對對象進行包裝,實現(xiàn)深層響應式。核心區(qū)別在于:Ref主要用于原始類型或需要通過`.value`訪問的場景,而Reactive用于對象類型;Ref的`value`屬性是響應式的觸發(fā)點,修改時需顯式操作`.value`,而Reactive通過Proxy攔截對象屬性的修改自動觸發(fā)更新。實際使用中,若處理原始類型(如`count:number`)或需要在模板中直接訪問(無需解構),應優(yōu)先用Ref;處理對象或數(shù)組時,用Reactive更直觀。需注意,對Reactive對象解構會丟失響應性,需通過toRef或toRefs轉(zhuǎn)換;Ref在模板中訪問時可省略`.value`,但在JS中必須顯式訪問。組合式API中,setup函數(shù)的執(zhí)行時機和生命周期鉤子的對應關系是怎樣的?為什么推薦使用組合式API?Setup函數(shù)在組件實例創(chuàng)建后、初始化props和上下文后立即執(zhí)行,早于所有選項式API的生命周期鉤子(除beforeCreate和created)。具體對應關系:setup執(zhí)行在beforeCreate之前(Vue3中beforeCreate和created被廢棄,邏輯移至setup),setup返回的對象會暴露給模板和其他生命周期鉤子。組合式API推薦的核心原因是解決選項式API的邏輯復用問題:選項式API按功能劃分(data、methods、computed),導致復雜邏輯(如表單驗證、數(shù)據(jù)請求)分散在不同選項中,難以復用;組合式API通過提取邏輯函數(shù)(如`useFetchData`),將相關邏輯集中,提高代碼可維護性和復用性。此外,組合式API更好支持TypeScript類型推導,減少類型聲明的冗余,且在Tree-shaking時更友好,未使用的邏輯可被剔除,減小包體積。Vue3模板編譯優(yōu)化中,靜態(tài)提升、PatchFlag和Block樹分別解決了什么問題?靜態(tài)提升(StaticHoisting)將模板中不變化的節(jié)點(如純文本、靜態(tài)class)提取為常量,避免每次渲染重復創(chuàng)建。例如`<div>靜態(tài)文本</div>`會被提升為`const_hoisted_1=<div>靜態(tài)文本</div>`,后續(xù)渲染直接復用,減少內(nèi)存分配。PatchFlag(補丁標記)用于標記動態(tài)節(jié)點的類型(如文本、class、樣式),在diff時僅檢查被標記的動態(tài)屬性,而非全量比較。例如`<!--1-->`表示該節(jié)點有動態(tài)文本,diff時只更新文本內(nèi)容,提升效率。Block樹(BlockTree)通過將動態(tài)節(jié)點及其子樹組織為Block,保留動態(tài)節(jié)點的層級關系,避免遞歸遍歷整個虛擬DOM樹。例如一個包含動態(tài)`v-for`的容器,會被標記為Block,其內(nèi)部動態(tài)子節(jié)點的PatchFlag會被收集,diff時僅處理Block內(nèi)的動態(tài)節(jié)點,大幅減少需要比較的節(jié)點數(shù)量。這三者結(jié)合,使Vue3的模板渲染性能相比Vue2提升約1.5-2倍。Vue3的diff算法相比Vue2有哪些優(yōu)化?最長遞增子序列(LIS)在此過程中起什么作用?Vue3的diff算法優(yōu)化主要體現(xiàn)在:1.預處理頭尾部相同節(jié)點:先比較新舊子節(jié)點數(shù)組的頭部和尾部,若相同則直接跳過,減少需要處理的節(jié)點數(shù)量;2.使用PatchFlag標記動態(tài)節(jié)點,僅對動態(tài)節(jié)點進行diff;3.引入LIS優(yōu)化移動操作。在子節(jié)點順序變化的場景中,Vue2通過雙指針遍歷,復雜度為O(n2);Vue3則先找出新舊節(jié)點的索引映射,過濾出需要移動或新增的節(jié)點,然后對剩余節(jié)點的新索引數(shù)組計算LIS。LIS是當前節(jié)點順序中最長的無需移動的子序列,數(shù)組長度外的節(jié)點即為需要移動的節(jié)點。例如舊索引數(shù)組為[1,3,4,2],LIS為[1,3,4](長度3),則只需移動索引2的節(jié)點,而非全部調(diào)整順序。這將復雜度從O(n2)降至O(nlogn),顯著提升大規(guī)模列表的diff效率。Pinia相比Vuex的核心優(yōu)勢有哪些?如何在Pinia中實現(xiàn)狀態(tài)的持久化?Pinia的核心優(yōu)勢:1.更簡潔的API:去除了mutations(僅保留actions),通過`defineStore`定義store,直接修改狀態(tài)(需配合`storeToRefs`保持響應性);2.類型安全:原生支持TypeScript,通過泛型和類型推斷自動推導state、getters、actions的類型,減少手動聲明;3.模塊化設計:每個store獨立定義,無需集中式注冊,支持Tree-shaking;4.更好的組合式API支持:可在setup中直接使用store,或通過組合式函數(shù)封裝邏輯;5.輕量高效:體積更小(約1KB),狀態(tài)更新直接通過Proxy攔截,性能更優(yōu)。實現(xiàn)狀態(tài)持久化可通過插件機制,例如使用`pinia-plugin-persistedstate`。該插件會在store初始化時從`localStorage`(或其他存儲)讀取狀態(tài),并在狀態(tài)變更時自動保存。自定義實現(xiàn)需在store的`$subscribe`鉤子中監(jiān)聽變化,將state序列化后存入存儲,同時在store創(chuàng)建時從存儲中恢復初始狀態(tài)。例如:```javascript//自定義持久化插件constpersistPlugin=(context)=>{const{store}=context;conststorageKey=`pinia_${store.$id}`;//初始化時讀取constsavedState=localStorage.getItem(storageKey);if(savedState)store.$state=JSON.parse(savedState);//監(jiān)聽變化并保存store.$subscribe((mutation,state)=>{localStorage.setItem(storageKey,JSON.stringify(state));});};//注冊插件pinia.use(persistPlugin);```Vue3中如何實現(xiàn)自定義指令?指令的生命周期鉤子有哪些?在指令中如何訪問組件實例或響應式數(shù)據(jù)?自定義指令通過`app.directive`全局注冊或在組件`directives`選項中局部注冊。指令的生命周期鉤子包括:`beforeMount`(元素剛插入DOM時)、`mounted`(元素掛載完成)、`beforeUpdate`(元素更新前)、`updated`(元素更新后)、`beforeUnmount`(元素卸載前)、`unmounted`(元素卸載后)。鉤子函數(shù)接收`el`(綁定元素)、`binding`(包含`value`、`oldValue`、`arg`、`modifiers`等屬性)、`vnode`(當前虛擬節(jié)點)、`prevVnode`(上一個虛擬節(jié)點)四個參數(shù)。訪問組件實例需通過`ponent`(僅當指令綁定在組件上時有效),但需注意`vnode`可能為`null`或`undefined`,需做安全校驗。訪問響應式數(shù)據(jù)時,若指令綁定的值是響應式的(如`v-my-directive="reactiveData"`),需在`beforeUpdate`或`updated`鉤子中監(jiān)聽變化,或使用`watch`函數(shù)(在指令中通過`getCurrentInstance`獲取組件實例后使用)。例如,在指令中監(jiān)聽響應式值的變化:```javascriptapp.directive('highlight',{mounted(el,binding){el.style.backgroundColor=binding.value.color;//監(jiān)聽值變化(需在組件實例上下文中使用watch)constinstance=getCurrentInstance();if(instance){watch(()=>binding.value.color,(newColor)=>{el.style.backgroundColor=newColor;});}}});```VueRouter4.x中,導航守衛(wèi)的執(zhí)行順序是怎樣的?如何處理動態(tài)路由的權限控制?導航守衛(wèi)的執(zhí)行順序為:1.全局前置守衛(wèi)`beforeEach`;2.解析守衛(wèi)`beforeResolve`(在所有組件內(nèi)守衛(wèi)和異步路由組件加載完成后執(zhí)行);3.全局解析守衛(wèi)`beforeResolve`(與步驟2合并,實際為同一階段);4.全局后置鉤子`afterEach`。組件內(nèi)守衛(wèi)的執(zhí)行順序:`beforeRouteEnter`(在導航確認前,組件實例未創(chuàng)建)→`beforeRouteUpdate`(組件復用時,參數(shù)變化時觸發(fā))→`beforeRouteLeave`(離開當前組件時觸發(fā))。處理動態(tài)路由權限控制的典型流程:1.用戶登錄后獲取權限角色;2.根據(jù)角色提供可訪問的路由配置(如通過`filter`過濾動態(tài)路由表);3.使用`router.addRoute`動態(tài)添加路由;4.在全局前置守衛(wèi)`beforeEach`中檢查當前路徑是否已授權:若未匹配到路由,嘗試添加動態(tài)路由后重新導航;若仍未匹配,跳轉(zhuǎn)至404頁。需注意,動態(tài)路由添加后需調(diào)用`router.push(to.path)`觸發(fā)重定向,避免白屏。示例代碼:```javascriptrouter.beforeEach(async(to,from,next)=>{consthasToken=localStorage.getItem('token');if(hasToken){if(to.path==='/login'){next('/');//已登錄跳轉(zhuǎn)首頁}else{consthasRoutes=router.getRoutes().some(r=>r.path===to.path);if(!hasRoutes){constdynamicRoutes=awaitgetDynamicRoutes(userRole);//獲取動態(tài)路由dynamicRoutes.forEach(route=>router.addRoute(route));next({...to,replace:true});//重新導航}else{next();}}}else{if(whiteList.includes(to.path)){//白名單路徑(如登錄頁)next();}else{next('/login');}}});```Vue3中如何優(yōu)化大型組件的渲染性能?Suspense和異步組件在其中起什么作用?優(yōu)化大型組件渲染性能的策略包括:1.拆分組件:將復雜組件拆分為更小的子組件,利用`v-if`/`v-show`或動態(tài)組件延遲加載非關鍵部分;2.使用`v-memo`緩存靜態(tài)或變化少的子樹:例如`v-memo="[item.id,item.value]"`,僅當依賴項變化時重新渲染;3.避免在模板中使用復雜表達式:將計算邏輯移至`computed`或方法中,減少渲染時的計算開銷;4.使用`keep-alive`緩存高頻訪問的組件:保留組件狀態(tài),避免重復渲染;5.優(yōu)化響應式數(shù)據(jù):避免將大對象或數(shù)組作為響應式數(shù)據(jù),使用`shallowReactive`或`shallowRef`減少不必要的依賴跟蹤。Suspense用于包裹異步組件或需要等待異步操作(如數(shù)據(jù)請求)的組件樹,提供加載狀態(tài)(通過`default`和`fallback`插槽)。異步組件通過`defineAsyncComponent`定義,可配合Suspense實現(xiàn)分步加載:主組件先渲染`fallback`內(nèi)容,待異步組件加載完成后替換為實際內(nèi)容,避免主線程阻塞。例如:```vue<template><Suspense><templatedefault><AsyncComponent/><!--異步加載的大型組件--></template><templatefallback><div>加載中...</div></template></Suspense></template><script>import{defineAsyncComponent}from'vue';constAsyncComponent=defineAsyncComponent(()=>import('./LargeComponent.vue'));</script>```Vue3與TypeScript集成時,如何正確定義組件的Props和emits?如何為全局屬性添加類型聲明?定義Props時,使用`defineComponent`配合`PropType`明確類型。例如:```typescriptimport{defineComponent,PropType}from'vue';exportdefaultdefineComponent({props:{user:{type:ObjectasPropType<{name:string;age:number}>,required:true},count:{type:Number,default:0}}});```定義emits時,通過對象形式聲明事件參數(shù)類型:```typescriptexportdefaultdefineComponent({emits:{'user-updated':(payload:{id:number;name:string})=>{//校驗邏輯returnpayload.id>0;}},methods:{handleUpdate(){this.$emit('user-updated',{id:1,name:'Alice'});}}});```為全局屬性(如`app.config.globalProperties`)添加類型聲明,需擴展`ComponentCustomProperties`接口。例如,添加全局`$http`方法:```typescript//shims-global.d.tsimport{ComponentCustomProperties}from'vue';import{Http}from'./http';declaremodule'@vue/runtime-core'{interfaceComponentCustomProperties{$http:Http;}}//注冊全局屬性app.config.globalProperties.$http=newHttp();```這樣在組件中使用`this.$http`時,TypeScript會自動推斷類型。Vue3響應式系統(tǒng)中,如何手動觸發(fā)依賴收集和更新?`effect`和`watch`的核心區(qū)別是什么?手動觸發(fā)依賴收集可通過`track`函數(shù)(需在`effect`作用域內(nèi)),觸發(fā)更新通過`trigger`函數(shù)。例如,在自定義響應式對象中:```javascriptimport{track,trigger}from'v

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論