?一、技術棧與編碼能力(10min)
1. Vue 3 & Composition API
Q1:請解釋一下?ref
?和?reactive
?的區別?你在項目中是如何使用的?
答:ref是包裝一個原始值或對象,通過.value訪問,reactive是對對象的深度響應式處理,不能用于原始值。 在模板中使用,ref會自動解包,不需要寫.value,而reactive直接訪問屬性即可。
加分點:toRefs的作用及如何在組合函數中使用它。提到<script setup>中自動解包機制。
toRefs是Vue3組合式API中的一個工具函數。當解構reactive創建的響應式對象時,直接解構會失去響應式,toRefs可解決這個問題。toRefs用于將響應式對象的每個屬性轉換為獨立的ref,保持屬性的響應式并避免解構時丟失響應式。toRefs轉換后的屬性是ref。需通過.value訪問值,toRefs只能處理reactive創建的對象。
組合函數返回的狀態:return toRefs(reactiveObj)
Q2:<script setup>
?和傳統?<script>
?有什么不同?它的優勢和局限是什么?
答:<script setup>是vue3的語法糖,簡化了組合式API的使用,優勢是不需要顯式的setup()函數,默認導出變量為組件的公開API ,自動引入defineProps、defineEmits等編譯器宏。不利于代碼復用(可結合自定義的Hook解決)
Q3:Vue 3 中的響應式原理和 Vue 2 有何不同?
答:vue2使用Object.defineProperty實現響應式,只能攔截對象已有屬性的變化,無法檢測新增、刪除屬性。通過data()函數返回對象,無法單獨暴露響應式對象,必須依賴組件實例,通過this訪問。不支持Map、Set等ES6集合類型 vue2中的map不是響應式的
Vue3用Proxy代理整個對象,動態攔截所有操作(包括新增、刪除屬性,數組索引修改),支持深層響應式。使用ref和reactive創建獨立響應式變量,可將響應式狀態和邏輯提取到組合函數中。map是響應式的,需用ref和reactive包裹進行顯示轉換(const map = reactive(new Map())
功能 | Vue 2 | Vue 3 |
---|---|---|
創建響應式對象 | data() ?+?Vue.observable() | reactive() ?/?ref() |
新增響應式屬性 | Vue.set() | 直接賦值(Proxy 自動支持) |
刪除響應式屬性 | Vue.delete() | 直接?delete |
數組響應式 | 重寫方法(如?push ) | 原生支持索引修改 |
響應式工具 | 無 | toRefs 、toRef 、isReactive |
2. TypeScript
Q4:你是如何組織?/types/
?下的類型的?有使用過?type?還是?interface
?為什么?
答:通常將接口模型放在/types下,按模塊分目錄結構
使用interface定義對象結構,方便擴展和繼承,使用type定義聯合類型,交叉類型、泛型等復雜結構
泛型:用類型變量(如<T>)表示動態類型,T由調用時決定。
聯合類型:允許一個變量或參數同時支持多種類型,通過 | 符號連接,擴展類型的靈活性。
交叉類型:用 & 符號將多個類型合并為一個包含所有成員的新類型,“與”的關系,一個值滿足多個類型的約束。
-
3. 組件通信與復用
Q5:舉個例子說明你使用過?provide/inject
?或?Pinia/Vuex
?的場景。
provide/inject
:用于跨層級傳遞主題配置、語言設置等上下文信息。
// 父組件
provide('theme', 'dark');// 子組件
inject('theme');
Pinia
:用于全局狀態管理,如用戶登錄狀態、收藏學校列表。
const userStore = useUserStore();
userStore.login();
二、項目架構與工程實踐(10min)
4. 模塊劃分與組織結構
Q7:請介紹一下項目的整體結構(如?/pages
,?/components
,?/stores
,?/types
?等目錄的作用)。
答:
/pages
:頁面級組件,對應路由。/components
:通用組件庫,如按鈕、標簽、導航欄等。/stores
:狀態管理模塊,使用 Pinia。/types
:類型定義文件,按模塊劃分。/common
:公共工具類和網絡請求封裝。
5. 接口調用與網絡層設計
Q8:你是如何封裝網絡請求模塊的?是否統一處理了錯誤、攔截器、Token 刷新?
- 使用 Axios 或 UniApp 原生?
uni.request
?封裝了一個統一的?http.ts
。 - 添加了請求攔截器(添加 Token)、響應攔截器(統一錯誤提示)。
- 錯誤碼集中處理(如 401 登錄失效跳轉登錄頁)。
- Token 刷新機制(如使用 refresh token)。
6. 狀態管理
Q9:項目中使用的是 Pinia 嗎?為什么選擇它而不是 Vuex?
- 優點:
- 更簡潔的 API,無需?
mutations
。 - 支持模塊化、命名空間。
- 更好的 TypeScript 支持。
- 性能更優,體積更小。
- 更簡潔的 API,無需?
Vuex需要定義mutation/actions/getters,基于Vue2的響應式系統
Pinia直接使用Composition API風格,無需mutations,直接通過actions修改狀態,基于Vue3的響應式系統(Proxy實現),按需加載store ,僅支持Vue3
三、性能與調試(5min)
7. 性能優化
Q10:你是如何做頁面加載優化的?比如懶加載、骨架屏、分包等。
- 使用 Vue 的異步組件實現懶加載。
- 頁面首屏采用骨架屏減少白屏時間。
- 使用 uni.preloadPages 實現頁面預加載。
- 對大型功能模塊進行分包(subpackages)。
- 圖片懶加載、CDN 加速。
四、協作與測試(5min)
8. Git 協作流程
Q11:團隊中是如何進行 Git 分支管理的?有使用 PR 流程嗎?
答:有一個主分支develop ,再每個人建立自己的功能分支,開發完成后提交pr,合并,處理沖突
Q12:有沒有使用過自定義 Hook 來封裝邏輯復用?
答:有,在多個組件中復用篩選、排序、搜索等功能,使用自定義的Hook.
function useFilter(list) {const filteredList = computed(() => filterLogic(list.value));return { filteredList };
}
Hook(鉤子)是編程中的一種攔截或擴展程序執行的流程技術,允許開發者在特定階段插入自定義的代碼,不同場景Hook的實現和用途不同