主頁 > 前端設計 > 「offer來了」從基礎到進階原理,從vue2到vue3,48個知識點保姆級帶你鞏固vuejs知識體系

「offer來了」從基礎到進階原理,從vue2到vue3,48個知識點保姆級帶你鞏固vuejs知識體系

2021-11-15 11:18:20 前端設計

封面

「面試專欄」前端面試之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 來說,我們需要從 vue2vue3 來做一個基本的學習,以更好的應對面試官的各種刁難問題,

在下面的這篇文章中,將從 vue2 的基礎知識,到 vue2 的原理知識,再到 vue3 的基礎知識和原理知識做一個歸納和總結,同時,周一也將整理出相關的面試題,以供大家可以有一個更好的參考,

下面開始進入本文的講解~

🎙?一、vue2.x基礎知識預備

在了解常見的面試題之前,需要先對 vue 的基礎知識有一個體系的了解,詳細見下圖👇

vue2.x基礎知識思維導圖

  • 關于以上內容,已整理成博文,戳下方鏈接進入學習👇

  • 原文:萬字總結vue的基本使用和高級特性,周邊插件vuex和vue-router

  • 鏈接:https://juejin.cn/post/6976040670939054093

📻二、vue2.x基礎知識常見面試題

基于以上知識點,我們將其細分為面試中的常考題,詳細見下圖👇

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 ,且不能是 indexrandom
  • 原因在于,在 vuediff 演算法中,通過對 tagkey 來判斷是否為相同節點 sameNode ,如果是相同節點,則會盡可能的復用原有的 DOM 節點,
  • 使用 key 的好處是:減少渲染次數,提升渲染性能,

5、描述Vue組件生命周期

(1)單組件生命周期

一般來說,組件生命周期的執行順序為:掛載階段 → 更新階段 → 銷毀階段,下面給出常用組件生命周期的決議,

生命周期鉤子介紹
beforeCreate在實體初始化之后,資料觀測(data observer) 和 event/watcher 事件配置之前被呼叫,
created頁面還沒有渲染,但是vue的實體已經初始化結束,
beforeMount在掛載開始之前被呼叫:相關的 render 函式首次被呼叫,
mounted頁面已經渲染完畢,
beforeUpdate資料更新時呼叫,發生在虛擬 DOM 重新渲染和打補丁之前,你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染程序,
updated由于資料更改導致的虛擬 DOM 重新渲染和打補丁,在這之后會呼叫該鉤子,當這個鉤子被呼叫時,組件 DOM 已經更新,所以你現在可以執行依賴于 DOM 的操作,
activatedkeep-alive 組件激活時呼叫,
deactivatedkeep-alive 組件停用時呼叫,
beforeDestroy實體銷毀之前呼叫,在這一步,實體仍然完全可用,常用場景有: 自定義事件的系結要解除、setTimeout等定時任務需要銷毀、自己系結的window或者document事件需要銷毀,
destroyedVue 實體銷毀后呼叫,呼叫后,Vue 實體指示的所有東西都會解系結,所有的事件監聽器會被移除,所有的子實體也會被銷毀,

(2)父子組件生命周期關系

加載渲染程序

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子組件更新程序

父beforeUpdate->子beforeUpdate->子updated->父updated

父組件更新程序

父beforeUpdate->父updated

銷毀程序

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

6、Vue組件如何通訊(常見)

vue 組件常見的通訊方式有以下三種:

  • 父子組件 propsthis.$emit
  • 自定義事件 event.$noevent.$offevent.$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 檔案編譯出來后是一個類;

  • 在每一個地方( datamethod ……)等等進行使用就是對 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-model
        2. 上面的 change1 和 model.event 要對應起來
        3. 上面的 text1 與下面props的 text1 屬性對應起來
    -->
</template>

<script>
export default {
    model: {
        prop: 'text1', // 對應下面 props 的 text1
        event: '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 結果是一樣的,至此,我們就實作了自定義的 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-showv-if
  • 合理使用 computed
  • v-for 時加 key ,以及避免和 v-if 同時使用
  • 自定義事件、 DOM 事件及時銷毀
  • 合理使用異步組件
  • 合理使用 keep-alive
  • data 層級不要太深,盡量扁平
  • 使用 vue-loader 在開發環境做模板編譯(預編譯)
  • 合理使用 keep-alive
  • webpack 層面的優化
  • 使用 SSR

📟三、vue2.x原理知識預備

在了解常見的面試題之前,需要先對 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原理知識常見面試題

基于以上知識點,我們將其細分為面試中的常考題,詳細見下圖👇

vue2.x原理知識面試題整理

接下來對這些題目進行一一解答,

1、對MVVM的理解

所謂 MVVM ,即 Model-View-ViewModel

View視圖 ,也就是 DOM

Model模型 ,可以理解為 Vue 中組件里面的 data

那么這兩者之間,就通過 ViewModel 來做關聯,而 ViewModel 可以做的事情有很多,比如說像監聽事件,監聽指令等,當 Model 層的資料發生修改時,就可以通過 ViewModel ,來把資料渲染到 View 視圖層上,反之,當 View 層觸發 DOM 事件時,就可以通過 ViewModel ,從而使得 Model 層實作資料的修改,

這就是 Vue 中的資料驅動視圖,通過修改 Model 層的資料,來驅動到 View 的視圖中來,

MVVM

2、監聽data變化的核心 API 是什么

  • 所謂 vue 的回應式,即組件 data 的資料一旦變化,就會立刻觸發視圖的更新,實作資料驅動視圖的第一步,需要了解實作回應式的一個核心 API ,即 Object.defineProperty
  • 通過 Object.defineProperty ,我們可以實作對資料進行 getset 操作,即獲取資料修改資料的操作,從而達到對資料進行回應式的監聽,

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)

    // 核心 API
    Object.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 的基礎上,再執行 patchdiff

9、vue為何是異步渲染,$nextTick有何用?

  • vue 是組件級更新,一旦當前組件里的資料變了,那么它就會去更新這個組件,
  • 但是試想一下,如果當資料更改一次,組件就要去重新渲染一次,這樣對性能來說都是不太友好的,
  • 因此,為了防止資料一更新就更新組件,所以需要異步渲染來處理,
  • 而異步渲染的核心的方法就是 nextTick$nextTick 可以在 DOM 更新完之后,再觸發回呼

10、SPA單頁面應用是什么?

SPA,即單頁面應用(Single Page Application),所謂單頁 Web 應用,就是只有一張 Web 頁面的應用,單頁應用程式 (SPA) 是加載單個 HTML 頁面并在用戶與應用程式互動時動態更新該頁面的 Web 應用程式,瀏覽器一開始會加載必需的 HTMLCSSJavaScript ,所有的操作都在這張頁面上完成,都由 JavaScript 來控制,

現如今,為了配合單頁面 Web 應用快速發展的節奏,各類前端組件化技術堆疊層出不窮,近幾年來,通過不斷的版本迭代, vuereact 兩大技術堆疊脫穎而出,成為當下最受歡迎的兩大技術堆疊,

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 屬性,以便后續使用,
  • 通過 pushStatereplaceState 來實作無重繪跳轉的功能,
  • 使用 history 模式時,在對當前的頁面進行重繪時,此時瀏覽器會重新發起請求,如果 nginx 沒有匹配得到當前的 url ,就會出現 404 的頁面,
  • 而對于 hash 模式來說, 它雖然看著是改變了 url ,但不會被包括在 http 請求中,所以,它算是被用來指導瀏覽器的動作,并不影響服務器端,因此,改變 hash 并沒有真正地改變 url ,所以頁面路徑還是之前的路徑, nginx 也就不會攔截,
  • 因此,在使用 history 模式時,需要通過服務端來允許地址可訪問,如果沒有設定,就很容易導致出現 404 的局面,

12、hash和history兩者的選擇

  • to B 的系統推薦用 hash ,相對簡單且容易使用,且因為 hashurl 規范不敏感;
  • to C 的系統,可以考慮選擇 H5 history ,但是需要服務端支持
  • 能先用簡單的,就別用復雜的,要考慮成本和收益

🖨?五、vue3.x知識預備

關于 vue3 模塊,我將把基礎知識原理的內容結合在一起進行整理,詳細見下圖👇

vue3.x知識思維導圖

  • 關于以上內容,已整理成博文,戳下方鏈接進入學習👇

  • 原文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常見面試題

基于以上知識點,我們將其細分為面試中的常考題,詳細見下圖👇

vue3.x基礎知識面試題整理

接下來對這些題進行一一解答,

1、vue3和vue2有什么優勢?

  • vue3vue2 來說,性能上更好代碼體積更小,并且有更好的ts支持
  • 同時,更為突出的特點是, vue3更好的代碼組織能力,有更好的邏輯抽離能力,并且還有更多各式各樣的新功能
  • 其中尤為突出的就是大家平常耳熟能詳的 Composition APIOptions API

2、描述vue3生命周期

以下給出 Vue2Vue3 生命周期的對比,

Vue2生命周期(Options API)Vue3生命周期(Composition API)含義
beforeCreatesetup在實體初始化之后,資料觀測(data observer) 和 event/watcher 事件配置之前被呼叫
createdsetup頁面還沒有渲染,但是vue的實體已經初始化結束,
beforeMountonBeforeMount在掛載開始之前被呼叫:相關的 render 函式首次被呼叫,
mountedonMounted頁面已經渲染完畢,
beforeUpdateonBeforeUpdate資料更新時呼叫,發生在虛擬 DOM 重新渲染和打補丁之前,你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染程序,
updatedonUpdated由于資料更改導致的虛擬 DOM 重新渲染和打補丁,在這之后會呼叫該鉤子,當這個鉤子被呼叫時,組件 DOM 已經更新,所以你現在可以執行依賴于 DOM 的操作,
beforeDestoryonBeforeUnmount實體銷毀之前呼叫,在這一步,實體仍然完全可用,
destroyonUnmountedVue 實體銷毀后呼叫,

3、如何看待Composition API和Options API

對于 Composition APIOptions 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 如果用于普通物件(非回應式物件),產出的結果不具備回應式,如下代碼所示:

//普通物件
const state = {
	age: 20,
	name: 'monday'
}
//回應式物件
const state = reactive({
    age: 20,
    name: 'monday'
})

(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 只會被呼叫一次,而后者函式會被多次呼叫,
  • 前者無需 useMemouseCallback (即快取資料和快取函式),因為 setup 只呼叫一次,
  • 前者無需顧慮呼叫順序,而后者需要保證 hooks 的順序一致,
  • 前者 reactive+ref 比后者的 useState ,要難理解,

📸七、結束語

vue2.x 的基礎知識,再到 vue2.x 的原理知識,最后到 vue3.x 的新特性和原理知識學習,全文貫穿著 vue 的知識要點及相關知識點所涉及到的一些面試題,

最后,關于這部分內容已整理成 PDF ,獲取方式放在彩蛋里面,有需要的小伙伴自取o!

🐣彩蛋 One More Thing

🏷?往期推薦

vue2.xvue3.x 的原理學習,累計博文輸出 11 篇,以下是相關專欄文章~

  • vue.js基礎知識👉基礎知識專欄傳送門
  • vue.js原理知識👉原理知識專欄傳送門

面試專欄 pdf 版本:

  • 微信搜索 星期一研究室 并關注,回復關鍵詞 vue面試pdf 獲取相關資料~

  • 回復 面試大全pdf 可獲取全系列資料!

更新地址:

  • offer來了面試專欄

🏷?番外篇

  • 如果這篇文章對你有用,記得留個腳印jio再走哦~
  • 以上就是本文的全部內容!我們下期見!👋👋👋

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/357140.html

標籤:其他

上一篇:純前端實作—“王者榮耀開局十秒倒計時效果”

下一篇:顫振中的函式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more