vue基礎知識點

說說你對MVVM的理解

  • Model-View-ViewModel的縮寫,Model代表數據模型,View代表UI組件,ViewModel將Model和View關聯起來。

  • 數據會綁定到viewModel 層並自動將數據渲染到頁面中,視圖變化時候會通知viewModel層更新數據。

vue2.x響應式數據/雙向綁定原理

  •   Vue數據雙向綁定主要是指:數據變化更新視圖,視圖變化更新數據。其中,View變化更新Data,可以通過實踐監聽的方式來實現,所以Vue數據雙向綁定的的工作主要是如何根據Data變化更新View

       簡述:

當你把一個普通的javaScript對象傳入Vue實例作爲data選項,Vue將遍歷此對象所有的property,並使用Object.defineProperty把這些property全部轉爲getter/setter。

  • 這些getter/setter對用戶來說是不可兼得,但是在內部他們讓Vue能夠追蹤依賴,在property被訪問和修改時通知變更。

  • 每個組件實例都對應一個watcher實例,他會在組件渲染的過程中吧“接觸”過的數據Property記錄爲依賴之後當依賴項的setter觸發時,會通知watcher,從而使他關聯的組件重新渲染。

  • 深入理解:

    • 監聽器 Observer:對數據對象進行遍歷,包括子屬性對象的屬性,利用 Object.defineProperty() 對屬性都加上 setter 和 getter。這樣的話,給這個對象的某個值賦值,就會觸發 setter,那麼就能監聽到了數據變化。

    • 解析器 Compile:解析 Vue 模板指令,將模板中的變量都替換成數據,然後初始化渲染頁面視圖,並將每個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變動,收到通知,調用更新函數進行數據更新。

    • 訂閱者 Watcher:Watcher 訂閱者是 Observer 和 Compile 之間通信的橋樑 ,主要的任務是訂閱 Observer 中的屬性值變化的消息,當收到屬性值變化的消息時,觸發解析器 Compile 中對應的更新函數。每個組件實例都有相應的 watcher 實例對象,它會在組件渲染的過程中把屬性記錄爲依賴,之後當依賴項的 setter 被調用時,會通知 watcher 重新計算,從而致使它關聯的組件得以更新——這是一個典型的觀察者模式

    • 訂閱器 Dep:訂閱器採用 發佈-訂閱 設計模式,用來收集訂閱者 Watcher,對監聽器 Observer 和 訂閱者 Watcher 進行統一管理。

 

你知道Vue3.x響應式數據原理嗎?

Vue3.x改用Proxy替代Object.defineProperty

  • 因爲Proxy可以直接監聽對象和數組的變化,並且有多達13種攔截方法。並且作爲新標準將受到瀏覽器廠商重點持續的性能優化。

  • Proxy只會代理對象的第一層,Vue3是怎樣處理這個問題的呢?

    • 判斷當前Reflect.get的返回值是否爲Object,如果是則再通過reactive方法做代理, 這樣就實現了深度觀測。

    • 監測數組的時候可能觸發多次get/set,那麼如何防止觸發多次呢?我們可以判斷key是否爲當前被代理對象target自身屬性,也可以判斷舊值與新值是否相等,只有滿足以上兩個條件之一時,纔有可能執行trigger。

      Proxy 與 Object.defineProperty 優劣對比

    • Proxy 的優勢如下:

      • Proxy 可以直接監聽對象而非屬性;

    • Proxy 可以直接監聽數組的變化;

      • Proxy 有多達 13 種攔截方法,不限於 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具備的;

      • Proxy 返回的是一個新對象,我們可以只操作新的對象達到目的,而 Object.defineProperty 只能遍歷對象屬性直接修改;

      • Proxy 作爲新標準將受到瀏覽器廠商重點持續的性能優化,也就是傳說中的新標準的性能紅利;

    • Object.defineProperty 的優勢如下:

      • 兼容性好,支持 IE9,而 Proxy 的存在瀏覽器兼容性問題,而且無法用 polyfill 磨平,因此 Vue 的作者才聲明需要等到下個大版本( 3.0 )才能用 Proxy 重寫。

VUEX篇

  • Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。每一個 Vuex 應用的核心就是 store(倉庫)。“store” 基本上就是一個容器,它包含着你的應用中大部分的狀態 ( state )。

    • Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地得到高效更新。

    • 改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化

    • 主要包括以下幾個模塊:

      • State:定義了應用狀態的數據結構,可以在這裏設置默認的初始狀態。

      • Getter:允許組件從 Store 中獲取數據,mapGetters 輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性。

      • Mutation:是唯一更改 store 中狀態的方法,且必須是同步函數。

      • Action:用於提交 mutation,而不是直接變更狀態,可以包含任意異步操作。

      • Module:允許將單一的 Store 拆分爲多個 store 且同時保存在單一的狀態樹中。

什麼情況下使用 Vuex?

  • 如果應用夠簡單,最好不要使用 Vuex,一個簡單的 store 模式即可

  • 需要構建一箇中大型單頁應用時,使用Vuex能更好地在組件外部管理狀態

組件中的data爲什麼是一個函數?

  • 一個組件被複用多次的話,也就會創建多個實例。本質上,這些實例用的都是同一個構造函數。

  • 如果data是對象的話,對象屬於引用類型,會影響到所有的實例。所以爲了保證組件不同的實例之間data不衝突,data必須是一個函數。

子組件爲什麼不可以修改父組件傳遞的Prop?/怎麼理解vue的單向數據流?

  • Vue提倡單向數據流,即父級props的更新會流向子組件,但是反過來則不行。
  • 這是爲了防止意外的改變父組件狀態,使得應用的數據流變得難以理解。

  • 如果破壞了單向數據流,當應用複雜時,debug 的成本會非常高。

v-model是如何實現雙向綁定的?

  • v-model是用來在表單控件或者組件上創建雙向綁定的

  • 他的本質是v-bind和v-on的語法糖

  • 在一個組件上使用v-model,默認會爲組件綁定名爲value的prop和名爲input的事件

nextTick的實現原理是什麼?

  • 在下次 DOM 更新循環結束之後執行延遲迴調,在修改數據之後立即使用 nextTick 來獲取更新後的 DOM。

  • nextTick主要使用了宏任務微任務

  • 根據執行環境分別嘗試採用Promise、MutationObserver、setImmediate,如果以上都不行則採用setTimeout定義了一個異步方法,多次調用nextTick會將方法存入隊列中,通過這個異步方法清空當前隊列。

    Vue不能檢測數組的哪些變動?Vue 怎麼用 vm.$set() 解決對象新增屬性不能響應的問題 ?

Vue 不能檢測以下數組的變動:

  1. 第一類問題

// 法一:

Vue.set Vue.set(vm.items, indexOfItem, newValue)

// 法二:

Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue) 複製代碼

   2. 第二類問題,可使用 splice:

vm.items.splice(newLength) 複製代碼

  • 當你利用索引直接設置一個數組項時,例如:vm.items[indexOfItem] = newValue

  • 當你修改數組的長度時,例如:vm.items.length = newLength

  • 解決辦法:

  • vm.$set 的實現原理是:

    • 如果目標是數組,直接使用數組的 splice 方法觸發相應式;

    • 如果目標是對象,會先判讀屬性是否存在、對象是否是響應式,最終如果要對屬性進行響應式處理,則是通過調用 defineReactive 方法進行響應式處理( defineReactive 方法就是 Vue 在初始化對象時,給對象屬性採用 Object.defineProperty 動態添加 getter 和 setter 的功能所調用的方法)

Vue事件綁定原理是什麼?

  • 原生事件綁定是通過addEventListener綁定給真實元素的,組件事件綁定是通過Vue自定義的$on實現的。

說一下虛擬Dom以及key屬性的作用

  • 由於在瀏覽器中操作DOM是很昂貴的。頻繁的操作DOM,會產生一定的性能問題。這就是虛擬Dom的產生原因。

  • Virtual DOM本質就是用一個原生的JS對象去描述一個DOM節點。是對真實DOM的一層抽象。(也就是源碼中的VNode類,它定義在src/core/vdom/vnode.js中。)

  • 虛擬 DOM 的實現原理主要包括以下 3 部分:

    • 用 JavaScript 對象模擬真實 DOM 樹,對真實 DOM 進行抽象;

    • diff 算法 — 比較兩棵虛擬 DOM 樹的差異;

    • pach 算法 — 將兩個虛擬 DOM 對象的差異應用到真正的 DOM 樹。

  • key 是爲 Vue 中 vnode 的唯一標記,通過這個 key,我們的 diff 操作可以更準確、更快速

    • 更準確:因爲帶 key 就不是就地複用了,在 sameNode 函數a.key === b.key對比中可以避免就地複用的情況。所以會更加準確。

    • 更快速:利用 key 的唯一性生成 map 對象來獲取對應節點,比遍歷方式更快

你的接口請求一般放在哪個生命週期中?

  • 可以在鉤子函數 created、beforeMount、mounted 中進行調用,因爲在這三個鉤子函數中,data 已經創建,可以將服務端端返回的數據進行賦值。

  • 但是推薦在 created 鉤子函數中調用異步請求,因爲在 created 鉤子函數中調用異步請求有以下優點:

    • 能更快獲取到服務端數據,減少頁面loading 時間;

    • ssr不支持 beforeMount 、mounted 鉤子函數,所以放在 created 中有助於一致性;

      路由篇

      vue路由hash模式和history模式實現原理分別是什麼,他們的區別是什麼?

    • hash 模式:

      • #後面 hash 值的變化,不會導致瀏覽器向服務器發出請求,瀏覽器不發出請求,就不會刷新頁面

      • 通過監聽 hashchange 事件可以知道 hash 發生了哪些變化,然後根據 hash 變化來實現更新頁面部分內容的操作。

    • history 模式:

      • history 模式的實現,主要是 HTML5 標準發佈的兩個 API,pushState 和replaceState,這兩個 API 可以在改變 url,但是不會發送請求。這樣就可以監聽 url 變化來實現更新頁面部分內容的操作

    • 區別

      • url 展示上,hash 模式有“#”,history 模式沒有

      • 刷新頁面時,hash 模式可以正常加載到 hash 值對應的頁面,而 history 沒有處理的話,會返回 404,一般需要後端將所有頁面都配置重定向到首頁路由

  •                兼容性,hash 可以支持低版本瀏覽器和 IE。

Vue-router 導航守衛有哪些

  • 全局前置/鉤子:beforeEach、beforeResolve、afterEach

  • 路由獨享的守衛:beforeEnter

  • 組件內的守衛:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

說說你對keep-alive組件的瞭解

  • keep-alive 是 Vue 內置的一個組件,可以使被包含的組件保留狀態,避免重新渲染 ,其有以下特性:

    • 一般結合路由和動態組件一起使用,用於緩存組件;

    • 提供 include 和 exclude 屬性,兩者都支持字符串或正則表達式, include 表示只有名稱匹配的組件會被緩存,exclude 表示任何名稱匹配的組件都不會被緩存 ,其中 exclude 的優先級比 include 高;

  • 對應兩個鉤子函數 activated 和 deactivated ,當組件被激活時,觸發鉤子函數 activated,當組件被移除時,觸發鉤子函數 deactivated。

說說你對SSR的瞭解

  • SSR也就是服務端渲染,也就是將Vue在客戶端把標籤渲染成HTML的工作放在服務端完成,然後再把html直接返回給客戶端

  • SSR的優勢

    • 更好的SEO

    • 首屏加載速度更快

  • SSR的缺點

    • 開發條件會受到限制,服務器端渲染只支持beforeCreate和created兩個鉤子

    • 當我們需要一些外部擴展庫時需要特殊處理,服務端渲染應用程序也需要處於Node.js的運行環境

  • 更多的服務端負載

你都做過哪些Vue的性能優化?

編碼階段

  • 儘量減少data中的數據,data中的數據都會增加getter和setter,會收集對應的watcher

  • v-if和v-for不能連用

  • 如果需要使用v-for給每項元素綁定事件時使用事件代理

  • SPA 頁面採用keep-alive緩存組件

  • 在更多的情況下,使用v-if替代v-show

  • key保證唯一

  • 使用路由懶加載、異步組件

  • 防抖、節流

  • 第三方模塊按需導入

  • 長列表滾動到可視區域動態加載

  • 圖片懶加載

  • SEO優化

    • 預渲染

    • 服務端渲染SSR

  • 打包優化

    • 壓縮代碼

    • Tree Shaking/Scope Hoisting

    • 使用cdn加載第三方模塊

    • 多線程打包happypack

    • splitChunks抽離公共文件

    • sourceMap優化

  • 用戶體驗

    • 骨架屏

    • PWA

    • 還可以使用緩存(客戶端緩存、服務端緩存)優化、服務端開啓gzip壓縮等。

vue2.x中如何監測數組變化?

  • 使用了函數劫持的方式,重寫了數組的方法,Vue將data中的數組進行了原型鏈重寫,指向了自己定義的數組原型方法,當調用數組api時,可以通知依賴更新。

  • 如果數組中包含着引用類型,會對數組中的引用類型再次遞歸遍歷進行監控。這樣就實現了監測數組變化。

說說你對 SPA 單頁面的理解,它的優缺點分別是什麼?

  • SPA( single-page application )僅在 Web 頁面初始化時加載相應的 HTML、JavaScript 和 CSS。一旦頁面加載完成,SPA 不會因爲用戶的操作而進行頁面的重新加載或跳轉;取而代之的是利用路由機制實現 HTML 內容的變換,UI 與用戶的交互,避免頁面的重新加載。

  • 優點:

    • 用戶體驗好、快,內容的改變不需要重新加載整個頁面,避免了不必要的跳轉和重複渲染;

    • 基於上面一點,SPA 相對對服務器壓力小;

    • 前後端職責分離,架構清晰,前端進行交互邏輯,後端負責數據處理;

  • 缺點:

    • 初次加載耗時多:爲實現單頁 Web 應用功能及顯示效果,需要在加載頁面的時候將 JavaScript、CSS 統一加載,部分頁面按需加載;

    • 前進後退路由管理:由於單頁應用在一個頁面中顯示所有的內容,所以不能使用瀏覽器的前進後退功能,所有的頁面切換需要自己建立堆棧管理;

    • SEO 難度較大:由於所有的內容都在一個頁面中動態替換顯示,所以在 SEO 上其有着天然的弱勢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章