「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
「面試專欄」前端面試之vuejs篇
- 🖼?序言
- 🎙?一、vue2.x基礎知識預備
- 📻二、vue2.x基礎知識常見面試題
- 1、請說出vue.cli項目中src目錄每個文件夾和文件的用法?
- 2、vue.cli中怎樣使用自定義的組件?有遇到過哪些問題?
- 3、v-show和v-if的區別
- 4、為何v-for中要用key
- 5、描述Vue組件生命周期
- (1)單組件生命周期
- (2)父子組件生命周期關系
- 6、Vue組件如何通訊(常見)
- 7、描述組件渲染和更新的過程
- 8、vue如何處理刷新數據不丟失
- 9、雙向數據綁定 v-model 的實現原理
- 10、computed 有何特點
- 11、為何組件data必須是一個函數
- 12、ajax請求應該放在哪個生命周期
- 13、如何將組件所有props傳遞給子組件?
- 14、如何自己實現v-model
- 15、多個組件有相同的邏輯,如何抽離?
- 16、何時要使用異步組件
- 17、何時使用keep-alive
- 18、何時需要使用beforeDestory
- 19、什么是作用域插槽
- 20、vuex中action和mutation有何區別
- 21、vue-router常用的路由模式
- 22、如何配置vue-router異步加載
- 23、scope是怎么實現的
- 24、vue常用性能優化方式
- 📟三、vue2.x原理知識預備
- 📠四、vue原理知識常見面試題
- 1、對MVVM的理解
- 2、監聽data變化的核心 API 是什么
- 3、vue如何監聽數組變化
- 4、請描述響應式原理
- 5、請用vnode描述一個DOM結構
- 6、diff算法的時間復雜度
- 7、簡述diff算法過程
- 8、vue模板編譯的原理是什么
- 9、vue為何是異步渲染,$nextTick有何用?
- 10、SPA單頁面應用是什么?
- 11、hash和history的區別是什么?
- (1)hash
- (2)history
- 12、hash和history兩者的選擇
- 🖨?五、vue3.x知識預備
- ??六、vue3.x常見面試題
- 1、vue3和vue2有什么優勢?
- 2、描述vue3生命周期
- 3、如何看待Composition API和Options API
- 4、如何理解ref、toRef和toRefs
- (1)ref是什么
- (2)toRef是什么
- (3)toRefs是什么
- 5、vue3升級了哪些重要的功能?
- 6、Composition API如何實現代碼的邏輯復用?
- 7、Vue3如何實現響應式?
- 8、Watch和watchEffect的區別是什么?
- 9、setup中如何獲取組件實例?
- 10、vue3為何比vue2快?
- 11、vite是什么?
- 12、Composition API和React hooks的對比
- 📸七、結束語
- 🐣彩蛋 One More Thing
- 🏷?往期推薦
- 🏷?番外篇
🖼?序言
對于前端來說, vuejs 是一大常考點。基本上只要候選人的簡歷上有涉及到 vue 的內容,那么面試官一般都會考察。那么,對于 vue 來說,我們需要從 vue2 到 vue3 來做一個基本的學習,以更好的應對面試官的各種刁難問題。
在下面的這篇文章中,將從 vue2 的基礎知識,到 vue2 的原理知識,再到 vue3 的基礎知識和原理知識做一個歸納和總結。同時,周一也將整理出相關的面試題,以供大家可以有一個更好的參考。
下面開始進入本文的講解~
🎙?一、vue2.x基礎知識預備
在了解常見的面試題之前,需要先對 vue 的基礎知識有一個體系的了解。詳細見下圖👇
-
關于以上內容,已整理成博文,戳下方鏈接進入學習👇
-
原文:萬字總結vue的基本使用和高級特性,周邊插件vuex和vue-router
-
鏈接:https://juejin.cn/post/6976040670939054093
📻二、vue2.x基礎知識常見面試題
基于以上知識點,我們將其細分為面試中的常考題。詳細見下圖👇
接下來對這些題進行一一解答。
1、請說出vue.cli項目中src目錄每個文件夾和文件的用法?
├── assets 放置靜態資源 ├── components 放組件 ├── router 定義路由的相關配置 ├── views 視圖 ├── app.vue 應用主組件 ├── main.js 入口文件2、vue.cli中怎樣使用自定義的組件?有遇到過哪些問題?
如何使用:
- 在 components 目錄新建你的組件文件( smithButton.vue );
- 在需要用的頁面中導入:import smithButton from '../components/smithButton.vue';
- 注入到 vue 的子組件的 components 屬性上,components:{smithButton}
- 在 template 視圖 view 中使用;
- 流程:創建組件→導入組件→注入組件→使用組件
會遇到的問題:
smithButton 命名,使用的時候需要用 smith-button ,在創建時常用到駝峰命名,但在使用時需把駝峰轉換為 - 表示;
vue 組件解決什么問題?
vue 組件可以提升整個項目的開發效率。能夠頁面抽象成多個相對獨立的模塊,解決了我們傳統項目開發效率低、難維護、復用性等等問題。
3、v-show和v-if的區別
- v-show 通過 css 中的 display 來控制顯示和隱藏;
- v-if 組件是真正的渲染和銷毀,而不是顯示和隱藏;
- 當頻繁切換顯示狀態時,用 v-show ,否則用 v-if 。
4、為何v-for中要用key
- 必須使用 key ,且不能是 index 和 random ;
- 原因在于,在 vue 的 diff 算法中,通過對 tag 和 key 來判斷是否為相同節點 sameNode ,如果是相同節點,則會盡可能的復用原有的 DOM 節點。
- 使用 key 的好處是:減少渲染次數,提升渲染性能。
5、描述Vue組件生命周期
(1)單組件生命周期
一般來說,組件生命周期的執行順序為:掛載階段 → 更新階段 → 銷毀階段。下面給出常用組件生命周期的解析。
| beforeCreate | 在實例初始化之后,數據觀測(data observer) 和 event/watcher 事件配置之前被調用。 |
| created | 頁面還沒有渲染,但是vue的實例已經初始化結束。 |
| beforeMount | 在掛載開始之前被調用:相關的 render 函數首次被調用。 |
| mounted | 頁面已經渲染完畢。 |
| beforeUpdate | 數據更新時調用,發生在虛擬 DOM 重新渲染和打補丁之前。你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。 |
| updated | 由于數據更改導致的虛擬 DOM 重新渲染和打補丁,在這之后會調用該鉤子。當這個鉤子被調用時,組件 DOM 已經更新,所以你現在可以執行依賴于 DOM 的操作。 |
| activated | keep-alive 組件激活時調用。 |
| deactivated | keep-alive 組件停用時調用。 |
| beforeDestroy | 實例銷毀之前調用。在這一步,實例仍然完全可用。常用場景有: 自定義事件的綁定要解除、setTimeout等定時任務需要銷毀、自己綁定的window或者document事件需要銷毀。 |
| destroyed | Vue 實例銷毀后調用。調用后,Vue 實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀。 |
(2)父子組件生命周期關系
加載渲染過程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted子組件更新過程
父beforeUpdate->子beforeUpdate->子updated->父updated父組件更新過程
父beforeUpdate->父updated銷毀過程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed6、Vue組件如何通訊(常見)
vue 組件常見的通訊方式有以下三種:
- 父子組件 props 和 this.$emit ;
- 自定義事件 event.$no 、 event.$off 和 event.$emit ;
- vuex 。
7、描述組件渲染和更新的過程
關于組件的渲染和更新過程,需要了解以下這張圖。大家可以從 1-6 依次按順序地對下圖的整個過程進行細化和解讀。
8、vue如何處理刷新數據不丟失
- 對 vuex 進行配置,將 vuex 的狀態儲存到 localStorage 中;
- 在頁面加載時讀取 localStorage 里的狀態信息;
- 在頁面刷新時將 vuex 里的信息保存到 localStorage 里;
- 在頁面中將 vuex 里的信息使用 computed 接收。
9、雙向數據綁定 v-model 的實現原理
-
input 元素的 value = this.name ;
-
綁定 input 事件 this.name = $event.target.value ;
-
data 更新后觸發重新渲染 re-render ;
-
最核心問題:了解 v-model 在模板編譯之后,產生的內容是什么。
10、computed 有何特點
-
具有緩存功能,當 data 不變時不會進行計算;
-
有效地提高性能。
11、為何組件data必須是一個函數
-
export 看似是一個對象,但是 .vue 文件編譯出來后是一個類;
-
在每一個地方( data , method ……)等等進行使用就是對 class 進行實例化;
-
我們在實例化的時候執行 data ;
-
如果這個 data 不是函數的話,那每一個組件的實例數據就都一樣了,就共享了;
-
因此需要讓它在閉包之中。
12、ajax請求應該放在哪個生命周期
-
mounted 表示整個渲染完成, dom 也加載完成,因此 ajax 請求應該放在 mounted 生命周期中;
-
本質上 js 是單線程的,并且 ajax 是異步獲取數據,是異步加載的一個機制;
-
如果將其放在 mounted 之前是沒有用的,這樣做只會讓邏輯更加混亂;
-
原因在于,如果在 mounted 之前放 ajax 請求,那么這個時候 js 還沒有渲染完成。且又因為 ajax 請求的數據還是異步的,因此即使是在 mounted 之前也不能加載,也不會有提前加載的效果。
13、如何將組件所有props傳遞給子組件?
-
父組件通過 $props 的而方式將自己的屬性傳遞給子組件;
-
之后子組件通過 <User v-bind = "$props" /> 這種方式去接收父組件傳遞過來的參數。
-
注: 細節知識點,優先級不高
14、如何自己實現v-model
第一步,我們先定義一個子組件,名字叫 CustomVModel.vue ,具體代碼如下:
<template><!-- $emit是子組件往父組件傳遞數據 --><input type="text":value="text1"@input="$emit('change1', $event.target.value)"><!--1. 上面的 input 使用了 :value 來綁定數據,而不是使用 v-model2. 上面的 change1 和 model.event 要對應起來3. 上面的 text1 與下面props的 text1 屬性對應起來--> </template><script> export default {model: {prop: 'text1', // 對應下面 props 的 text1event: 'change1'},props: {text1: String,default() {return ''}} } </script>第二步,我們在父組件中使用上面的這個子組件:
<template><div><p>vue 高級特性</p><hr><!-- 自定義 v-model --><p>{{name}}</p><CustomVModel v-model="name"/></div> </template><script> import CustomVModel from './CustomVModel'export default {components: {CustomVModel},data() {return {name: 'Monday'}} } </script>通過上面的代碼我們可以發現,通過綁定 value 屬性和 input 事件這兩個語法糖,最終實現數據的雙向綁定。
此時我們看下瀏覽器的顯示效果。
通過上圖我們自己發現,結果跟實際的 v-model 結果是一樣的。至此,我們就實現了自定義的 v-model ,以此來操作數據的雙向綁定。
15、多個組件有相同的邏輯,如何抽離?
-
在 vue2.x 中,當多個組件有相同的邏輯時,可以使用 mixin 來進行邏輯抽離;
-
值得注意的是, mixin 存在有以下問題:
- 變量來源不明確,不利于閱讀。
- 多個 mixin 可能會造成命名沖突。
- mixin 和組件可能出現多對多的關系,復雜度較高。
-
因此,要慎用 mixin ,且 vue3.x 已經出了 Composition API ,來解決 vue2.x 中存在的這些問題。
16、何時要使用異步組件
-
當加載大組件時,需要用到異步組件;
-
當 vue-router 路由要進行異步加載時,需要用到異步組件;
-
異步組件可以達到優化性能的效果。
17、何時使用keep-alive
-
keep-alive 可以緩存組件,使得組件不需要重復渲染;
-
比如像多個靜態 tab 頁的切換;
-
keep-alive 可以達到優化性能的效果。
18、何時需要使用beforeDestory
-
當解綁自定義事件 event.$off 時,需使用 beforeDestory 來對事件進行銷毀操作;
-
當使用定時器綁定時間時,在定時器操作結束時,需要清除定時器;
-
解綁自定義的 DOM 事件,如 window scroll 等,需要在 beforeDestory 生命周期來對其進行事件解綁。
注意: 如果以上三者不做的話,很容易造成內存泄漏。
19、什么是作用域插槽
- 父組件模板的所有東西只會在父級作用域內編譯;
- 子組件模板的所有東西只會在子集作用域內編譯;
- 而作用域插槽想解決的問題就是,讓父組件可以訪問到子組件的數據。
20、vuex中action和mutation有何區別
-
action 中可以處理異步, mutation 不可以;
-
mutation 做原子操作,即做一個操作,比較原子的;
-
action 可以整合多個 mutation ,可以理解為整理多個原子操作的集合。
21、vue-router常用的路由模式
-
hash 默認
-
H5 history (需要服務端支持)
-
已將路由模式整理成博客,具體戳下方鏈接👇
-
原文:淺談前端路由原理
-
鏈接:https://juejin.cn/post/6993840419041706014
22、如何配置vue-router異步加載
- 在 vue-router 中,使用 import 來實現異步加載。
23、scope是怎么實現的
(1)scoped的實現原理:
- 給 DOM 節點加一個不重復的屬性 data-v-5db9451a 來標志唯一性。
- 如果組件內部還有組件,只會給最外層的組件里的標簽加上唯一屬性字段,不影響組件內部引用的組件。
(2)vue中scoped的作用:
- 實現組件的私有化,當前 style 樣式屬性只屬于當前模塊,不污染全局。
- 但是當我們使用公共組件的時候會造成很多困難。
(3)謹慎使用:
- 父組件無 scoped 屬性,子組件帶有 scoped ,父組件是無法操作子組件的。
- 父組件有 scoped 屬性,子組件無 scoped 。父組件也無法設置子組件樣式。因為父組件的所有標簽都會帶有 data-v-5db9451a 唯一標志,但子組件不會帶有這個唯一標志屬性。
- 父子組件都有,同理也無法設置樣式,更改起來增加代碼量。
24、vue常用性能優化方式
- 合理使用 v-show 和 v-if
- 合理使用 computed
- v-for 時加 key ,以及避免和 v-if 同時使用
- 自定義事件、 DOM 事件及時銷毀
- 合理使用異步組件
- 合理使用 keep-alive
- data 層級不要太深,盡量扁平
- 使用 vue-loader 在開發環境做模板編譯(預編譯)
- 合理使用 keep-alive
- webpack 層面的優化
- 使用 SSR
📟三、vue2.x原理知識預備
在了解常見的面試題之前,需要先對 vue2.x 的原理知識有一個體系的了解。詳細見下圖👇
-
關于以上內容,已整理成博文,戳下方鏈接進入學習👇
-
原文1:手把手教你剖析vue響應式原理,監聽數據不再迷茫
-
鏈接1:https://juejin.cn/post/6978278417951096839
-
原文2:面試中的網紅虛擬DOM,你知多少呢?深入解讀diff算法
-
鏈接2:https://juejin.cn/post/6978621084862005285
-
原文3:模板編譯template的背后,究竟發生了什么事?帶你了解template的紙短情長
-
鏈接3:https://juejin.cn/post/6978965732633608222
📠四、vue原理知識常見面試題
基于以上知識點,我們將其細分為面試中的常考題。詳細見下圖👇
接下來對這些題目進行一一解答。
1、對MVVM的理解
所謂 MVVM ,即 Model-View-ViewModel 。
View 即 視圖 ,也就是 DOM 。
Model 即 模型 ,可以理解為 Vue 中組件里面的 data 。
那么這兩者之間,就通過 ViewModel 來做關聯。而 ViewModel 可以做的事情有很多,比如說像監聽事件,監聽指令等。當 Model 層的數據發生修改時,就可以通過 ViewModel ,來把數據渲染到 View 視圖層上。反之,當 View 層觸發 DOM 事件時,就可以通過 ViewModel ,從而使得 Model 層實現數據的修改。
這就是 Vue 中的數據驅動視圖,通過修改 Model 層的數據,來驅動到 View 的視圖中來。
2、監聽data變化的核心 API 是什么
- 所謂 vue 的響應式,即組件 data 的數據一旦變化,就會立刻觸發視圖的更新。實現數據驅動視圖的第一步,需要了解實現響應式的一個核心 API ,即 Object.defineProperty 。
- 通過 Object.defineProperty ,我們可以實現對數據進行 get 和 set 操作,即獲取數據和修改數據的操作,從而達到對數據進行響應式的監聽。
3、vue如何監聽數組變化
要想讓 Object.defineProperty() 這個 API 擁有監聽數組的能力,我們可以這么做。具體代碼如下:
// 觸發更新視圖 function updateView() {console.log('視圖更新') }// 重新定義數組原型 const oldArrayProperty = Array.prototype // 創建新對象,原型指向 oldArrayProperty ,再擴展新的方法不會影響原型 const arrProto = Object.create(oldArrayProperty); ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {arrProto[methodName] = function () {updateView() // 觸發視圖更新oldArrayProperty[methodName].call(this, ...arguments)// Array.prototype.push.call(this, ...arguments)} })// 重新定義屬性,監聽起來 function defineReactive(target, key, value) {// 深度監聽observer(value)// 核心 APIObject.defineProperty(target, key, {get() {return value},set(newValue) {if (newValue !== value) {// 深度監聽observer(newValue)// 設置新值// 注意,value 一直在閉包中,此處設置完之后,再 get 時也是會獲取最新的值value = newValue// 觸發更新視圖updateView()}}}) }// 監聽對象屬性 function observer(target) {if (typeof target !== 'object' || target === null) {// 不是對象或數組return target}// 污染全局的 Array 原型(如果直接定義在這里面,會直接污染全局)// Array.prototype.push = function () {// updateView()// ...// }if (Array.isArray(target)) {target.__proto__ = arrProto}// 重新定義各個屬性(for in 也可以遍歷數組)for (let key in target) {defineReactive(target, key, target[key])} }// 準備數據 const data = {name: 'monday',age: 20,info: {address: '深圳' // 需要深度監聽},nums: ['打籃球', '出來玩', '打乒乓球'] }// 監聽數據 observer(data)// 測試 data.info.address = '上海' // 深度監聽 data.nums.push('神游') // 監聽數組復制代碼此時瀏覽器的打印效果如下:
我們可以看到,兩個數據對應的視圖都更新了。通過對數組原型的重新定義,我們就讓 Object.defineProperty() 實現了監聽數組的能力。
4、請描述響應式原理
響應式原理概述:
- 任何一個 Vue 組件都會生成一個 render 函數。
- 之后 render 函數會生成一個 vnode 。
- 同時,在執行 render 函數的時候會觸發 data 里面的 getter ,觸發后則會生成依賴。
- 所謂依賴,就是在 data 觸發到哪個變量,就會將哪一個變量觀察起來。
- 之后,需要查看觸發到的這個變量是否是之前作為依賴被觀察起來的,如果是,則觸發 setter 進行數據修改;如果不是,則直接進行監聽操作;
- 最后,如果確定是之前作為依賴被重新觀察起來的,那就執行 re-render 重新渲染操作,并且進行 patch(vnode, newVnode) 。
5、請用vnode描述一個DOM結構
根據下方的 html 代碼,用 v-node 模擬出該 html 代碼的 DOM 結構。
html代碼:
<div id="div1" class="container"><p>vdom</p><ul style="font-size:20px;"><li>a</li></ul> </div> 復制代碼用JS模擬出以上代碼的DOM結構:
{tag: 'div',props:{className: 'container',id: 'div1'},children: [{tag: 'p',chindren: 'vdom'},{tag: 'ul',props:{ style: 'font-size: 20px' },children: [{tag: 'li',children: 'a'}// ....]}] }6、diff算法的時間復雜度
- 樹的時間復雜度是 O(n3) ,因此,我們就想辦法,優化其時間復雜度從O(n3)到O(n),以達到操作 vdom 節點,那這個優化過程其實我們所說的 diff 算法。
- 所以, diff 算法的時間復雜度為 O(n) 。
7、簡述diff算法過程
- 首先,對比節點本身,要先判斷是否為同一節點,如果不為相同節點,則刪除該節點重新創建節點進行替換;
- 如果為相同節點時,進行 patchVnode ,判斷如何對該節點的子節點進行處理,先判斷一方有子節點一方沒有子節點的情況(如果新的 children 沒有子節點,則將舊的子節點移除);
- 比較如果都有子節點,則進行 updateChildren ,判斷如何對這些新老節點的子節點進行操作( diff 核心)。
- 匹配時,找到相同的子節點,遞歸比較子節點。
注意: 在 diff 中,只對同層的子節點進行比較,放棄跨級的節點比較,使得時間復雜從 O(n^3) 降低值 O(n) ,也就是說,只有當新舊 children 都為多個子節點時才需要用核心的 diff 算法進行同層級比較。
8、vue模板編譯的原理是什么
- vue 在進行模板編譯之后,會先轉化成一個 render 函數,之后繼續執行 render 函數,執行完成之后返回一個 vnode ;
- 在得到 vnode 之后,基于 vnode 的基礎上,再執行 patch 和 diff 。
9、vue為何是異步渲染,$nextTick有何用?
- vue 是組件級更新,一旦當前組件里的數據變了,那么它就會去更新這個組件。
- 但是試想一下,如果當數據更改一次,組件就要去重新渲染一次,這樣對性能來說都是不太友好的。
- 因此,為了防止數據一更新就更新組件,所以需要異步渲染來處理。
- 而異步渲染的核心的方法就是 nextTick , $nextTick 可以在 DOM 更新完之后,再觸發回調。
10、SPA單頁面應用是什么?
SPA,即單頁面應用(Single Page Application)。所謂單頁 Web 應用,就是只有一張 Web 頁面的應用。單頁應用程序 (SPA) 是加載單個 HTML 頁面并在用戶與應用程序交互時動態更新該頁面的 Web 應用程序。瀏覽器一開始會加載必需的 HTML 、 CSS 和 JavaScript ,所有的操作都在這張頁面上完成,都由 JavaScript 來控制。
現如今,為了配合單頁面 Web 應用快速發展的節奏,各類前端組件化技術棧層出不窮。近幾年來,通過不斷的版本迭代, vue 和 react 兩大技術棧脫穎而出,成為當下最受歡迎的兩大技術棧。
11、hash和history的區別是什么?
(1)hash
- hash變化會觸發網頁跳轉,即瀏覽器的前進和后退。
- hash 可以改變 url ,但是不會觸發頁面重新加載(hash的改變是記錄在 window.history 中),即不會刷新頁面。也就是說,所有頁面的跳轉都是在客戶端進行操作。因此,這并不算是一次 http 請求,所以這種模式不利于 SEO 優化。hash 只能修改 # 后面的部分,所以只能跳轉到與當前 url 同文檔的 url 。
- hash 通過 window.onhashchange 的方式,來監聽 hash 的改變,借此實現無刷新跳轉的功能。
- hash 永遠不會提交到 server 端(可以理解為只在前端自生自滅)。
(2)history
- 新的 url 可以是與當前 url 同源的任意 url ,也可以是與當前 url 一樣的地址,但是這樣會導致的一個問題是,會把重復的這一次操作記錄到棧當中。
- 通過 history.state ,添加任意類型的數據到記錄中。
- 可以額外設置 title 屬性,以便后續使用。
- 通過 pushState 、 replaceState 來實現無刷新跳轉的功能。
- 使用 history 模式時,在對當前的頁面進行刷新時,此時瀏覽器會重新發起請求。如果 nginx 沒有匹配得到當前的 url ,就會出現 404 的頁面。
- 而對于 hash 模式來說, 它雖然看著是改變了 url ,但不會被包括在 http 請求中。所以,它算是被用來指導瀏覽器的動作,并不影響服務器端。因此,改變 hash 并沒有真正地改變 url ,所以頁面路徑還是之前的路徑, nginx 也就不會攔截。
- 因此,在使用 history 模式時,需要通過服務端來允許地址可訪問,如果沒有設置,就很容易導致出現 404 的局面。
12、hash和history兩者的選擇
- to B 的系統推薦用 hash ,相對簡單且容易使用,且因為 hash 對 url 規范不敏感;
- to C 的系統,可以考慮選擇 H5 history ,但是需要服務端支持;
- 能先用簡單的,就別用復雜的,要考慮成本和收益。
🖨?五、vue3.x知識預備
關于 vue3 模塊,我將把基礎知識和原理的內容結合在一起進行整理。詳細見下圖👇
-
關于以上內容,已整理成博文,戳下方鏈接進入學習👇
-
原文1: 一文了解vue3基礎新特性
-
鏈接1: https://juejin.cn/post/6976400439793172487
-
原文2: 敲黑板!vue3重點!一文了解Composition API新特性:ref、toRef、toRefs
-
鏈接2: https://juejin.cn/post/6976679225239535629
-
原文3: 一文get一波 vue3.x 進階新特性
-
鏈接3: https://juejin.cn/post/6976040670939054093
-
原文4: vue2的響應式原理學“廢”了嗎?繼續觀摩vue3響應式原理Proxy
-
鏈接4: https://juejin.cn/post/6979368550225936392
??六、vue3.x常見面試題
基于以上知識點,我們將其細分為面試中的常考題。詳細見下圖👇
接下來對這些題進行一一解答。
1、vue3和vue2有什么優勢?
- vue3 比 vue2 來說,性能上更好,代碼體積更小,并且有更好的ts支持。
- 同時,更為突出的特點是, vue3 有更好的代碼組織能力,有更好的邏輯抽離能力,并且還有更多各式各樣的新功能。
- 其中尤為突出的就是大家平常耳熟能詳的 Composition API 和 Options API 。
2、描述vue3生命周期
以下給出 Vue2 與 Vue3 生命周期的對比。
| beforeCreate | setup | 在實例初始化之后,數據觀測(data observer) 和 event/watcher 事件配置之前被調用 |
| created | setup | 頁面還沒有渲染,但是vue的實例已經初始化結束。 |
| beforeMount | onBeforeMount | 在掛載開始之前被調用:相關的 render 函數首次被調用。 |
| mounted | onMounted | 頁面已經渲染完畢。 |
| beforeUpdate | onBeforeUpdate | 數據更新時調用,發生在虛擬 DOM 重新渲染和打補丁之前。你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。 |
| updated | onUpdated | 由于數據更改導致的虛擬 DOM 重新渲染和打補丁,在這之后會調用該鉤子。當這個鉤子被調用時,組件 DOM 已經更新,所以你現在可以執行依賴于 DOM 的操作。 |
| beforeDestory | onBeforeUnmount | 實例銷毀之前調用。在這一步,實例仍然完全可用。 |
| destroy | onUnmounted | Vue 實例銷毀后調用。 |
3、如何看待Composition API和Options API
對于 Composition API 和 Options API 的使用,主要有以下幾點建議:
- 兩者不建議共用,不然很容易引起混亂;
- 對于小型項目、或者業務邏輯比較簡單的項目,建議使用 Options API ;
- 對于中大型項目、或者邏輯比較復雜的項目,建議使用 Composition API ,相較于 Options API 來說, Composition API 對大型項目更好一些,邏輯的抽離,代碼的復用,使得大型項目得以更好的維護。
4、如何理解ref、toRef和toRefs
(1)ref是什么
- ref 是可以生成 值類型(即基本數據類型) 的響應式數據;
- ref 可以用于模板和reactive;
- ref 通過 .value 來修改值(一定要記得加上 .value );
- ref 不僅可以用于響應式,還可以用于模板的 DOM 元素。
(2)toRef是什么
-
toRef 可以響應對象 Object ,其針對的是某一個響應式對象( reactive 封裝)的屬性 prop 。
-
toRef 和對象 Object 兩者保持引用關系,即一個改完另外一個也跟著改。
-
toRef 如果用于普通對象(非響應式對象),產出的結果不具備響應式。如下代碼所示:
(3)toRefs是什么
- 與 toRef 不一樣的是, toRefs 是針對整個對象的所有屬性,目標在于將響應式對象( reactive 封裝)轉換為普通對象。
- 普通對象里的每一個屬性 prop 都對應一個 ref 。
- toRefs 和對象 Object 兩者保持引用關系,即一個改完另外一個也跟著改。
5、vue3升級了哪些重要的功能?
- createApp
- emits(父子組件間的通信)
- 多事件處理
- Fragment
- 移除 .sync
- 異步組件
- 移除filter
- Teleport
- Suspense
6、Composition API如何實現代碼的邏輯復用?
- composition API 通過把代碼的邏輯抽離出來進行封裝,并把封裝的內容直接引用到生命周期里面,已達到代碼的邏輯復用效果。
7、Vue3如何實現響應式?
- 利用 reactive 注冊響應式對象,對函數返回值進行操作。
- 利用 Proxy 劫持數據的 get , set , deleteProperty , has , own 。
- 利用 WeakMap , Map , Set 來實現依賴收集。
- 缺點: 使用大量 ES6 新增特性,舊版本瀏覽器兼容性差。
8、Watch和watchEffect的區別是什么?
- 兩者都可以監聽 data 屬性變化;
- watch 需要明確監聽哪個屬性;
- 而 watchEffect 會根據其中的屬性,自動監聽其變化。
9、setup中如何獲取組件實例?
在 vue2 中, Options API 可以使用 this 來獲取組件的實例,但是到現在的 vue3 ,已經被摒棄掉了。在 setup 和其他 Composition API 中沒有 this ,但是它提供了一個 getCurrentInstance 來獲取當前的實例。
10、vue3為何比vue2快?
- Proxy響應式
- PatchFlag
- hoistStatic
- cacheHandler
- SSR優化
- tree-shaking
11、vite是什么?
- vite 是一個前端的打包工具,是 vue 作者發起的一個項目;
- vite 借助 vue 的影響力,發展較快,和 webpack 有著一定的競爭關系;
- 優勢: vite 使得程序在開發環境下無需打包,且啟動非常快速。
12、Composition API和React hooks的對比
- 前者 setup 只會被調用一次,而后者函數會被多次調用。
- 前者無需 useMemo和 useCallback (即緩存數據和緩存函數),因為 setup 只調用一次。
- 前者無需顧慮調用順序,而后者需要保證 hooks 的順序一致。
- 前者 reactive+ref 比后者的 useState ,要難理解。
📸七、結束語
從 vue2.x 的基礎知識,再到 vue2.x 的原理知識,最后到 vue3.x 的新特性和原理知識學習,全文貫穿著 vue 的知識要點及相關知識點所涉及到的一些面試題。
最后,關于這部分內容已整理成 PDF ,獲取方式放在彩蛋里面,有需要的小伙伴自取o!
🐣彩蛋 One More Thing
🏷?往期推薦
vue2.x 和 vue3.x 的原理學習,累計博文輸出 11 篇,以下是相關專欄文章~
- vue.js基礎知識👉基礎知識專欄傳送門
- vue.js原理知識👉原理知識專欄傳送門
面試專欄 pdf 版本:
-
微信搜索 星期一研究室 并關注,回復關鍵詞 vue面試pdf 獲取相關資料~
-
回復 面試大全pdf 可獲取全系列資料!
更新地址:
- offer來了面試專欄
🏷?番外篇
- 如果這篇文章對你有用,記得留個腳印jio再走哦~
- 以上就是本文的全部內容!我們下期見!👋👋👋
總結
以上是生活随笔為你收集整理的「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源IMDG之GridGain
- 下一篇: 「offer来了」从基础配置到高级配置,