国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

裝修網(wǎng)站開發(fā)前的準備工作百度推廣一個月多少錢

裝修網(wǎng)站開發(fā)前的準備工作,百度推廣一個月多少錢,wordpress左側(cè)產(chǎn)品分類目錄,如何制作有關(guān)西安的網(wǎng)站1. 談一談對 MVVM 的理解? MVVM 是 Model-View-ViewModel 的縮寫。MVVM 是一種設(shè)計思想。 Model 層代表數(shù)據(jù)模型,也可以在 Model 中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯; View 代表 UI 組件,它負責(zé)將數(shù)據(jù)模型轉(zhuǎn)化成 UI 展現(xiàn)出來,View 是…

1. 談一談對 MVVM 的理解?

MVVM 是 Model-View-ViewModel 的縮寫。MVVM 是一種設(shè)計思想。
Model 層代表數(shù)據(jù)模型,也可以在 Model 中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯;
View 代表 UI 組件,它負責(zé)將數(shù)據(jù)模型轉(zhuǎn)化成 UI 展現(xiàn)出來,View 是一個同步 View 和 Model 的對象
在 MVVM 架構(gòu)下,View 和 Model 之間并沒有直接的聯(lián)系,而是通過 ViewModel 進行交互, Model 和 ViewModel 之間的交互是雙向的, 因此 View 數(shù)據(jù)的變化會同步到 Model 中,而 Model 數(shù)據(jù)的變化也會立即反應(yīng)到 View 上。
對 ViewModel 通過雙向數(shù)據(jù)綁定把 View 層和 Model 層連接了起來,而 View 和 Model 之間的 同步工作完全是自動的,無需人為干涉,因此開發(fā)者只需關(guān)注業(yè)務(wù)邏輯,不需要手動操作 DOM,不需要關(guān)注數(shù)據(jù)狀態(tài)的同步問題,復(fù)雜的數(shù)據(jù)狀態(tài)維護完全由 MVVM 來統(tǒng)一管理。


2. 說一下 Vue 的優(yōu)點
?

Vue 是一個構(gòu)建數(shù)據(jù)驅(qū)動的 Web 界面的漸進式框架。

Vue 的目標是通過盡可能簡單的 API 實現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。核心是一個響應(yīng)的數(shù)據(jù)綁定系統(tǒng)。

關(guān)于 Vue 的優(yōu)點,主要有響應(yīng)式編程、組件化開發(fā)、虛擬 DOM

響應(yīng)式編程

這里的響應(yīng)式不是 @media 媒體查詢中的響應(yīng)式布局,而是指 Vue 會自動對頁面中某些數(shù)據(jù)的變化做出響應(yīng)。這也就是 Vue 最大的優(yōu)點,通過 MVVM 思想實現(xiàn)數(shù)據(jù)的雙向綁定,讓開發(fā)者不用再操作 DOM 對象,有更多的時間去思考業(yè)務(wù)邏輯。

組件化開發(fā)

Vue 通過組件,把一個單頁應(yīng)用中的各種模塊拆分到一個一個單獨的組件(component)中,我們只要先在父級應(yīng)用中寫好各種組件標簽(占坑),并且在組件標簽中寫好要傳入組件的參數(shù)(就像給函數(shù)傳入?yún)?shù)一樣,這個參數(shù)叫做組件的屬性),然后再分別寫好各種組件的實現(xiàn)(填坑),然后整個應(yīng)用就算做完了。

組件化開發(fā)的優(yōu)點:提高開發(fā)效率、方便重復(fù)使用、簡化調(diào)試步驟、提升整個項目的可維護性、便于協(xié)同開發(fā)。

虛擬 DOM

在傳統(tǒng)開發(fā)中,用 JQuery 或者原生的 JavaScript DOM 操作函數(shù)對 DOM 進行頻繁操作的時候,瀏覽器要不停的渲染新的 DOM 樹,導(dǎo)致在性能上面的開銷特別的高。

而 Virtual DOM 則是虛擬 DOM 的英文,簡單來說,他就是一種可以預(yù)先通過 JavaScript 進行各種計算,把最終的 DOM 操作計算出來并優(yōu)化,由于這個 DOM 操作屬于預(yù)處理操作,并沒有真實的操作 DOM,所以叫做虛擬 DOM。最后在計算完畢才真正將 DOM 操作提交,將 DOM 操作變化反映到 DOM 樹上。


3. 解釋一下對 Vue 生命周期的理解

什么是 vue 生命周期
vue 生命周期的作用是什么
vue 生命周期有幾個階段
第一次頁面加載會觸發(fā)哪幾個鉤子
DOM 渲染在哪個周期就已經(jīng)完成
多組件(父子組件)中生命周期的調(diào)用順序說一下
?

什么是 vue 生命周期

對于 vue 來講,生命周期就是一個 vue 實例從創(chuàng)建到銷毀的過程。

vue 生命周期的作用是什么

在生命周期的過程中會運行著一些叫做生命周期的函數(shù),給予了開發(fā)者在不同的生命周期階段添加業(yè)務(wù)代碼的能力。

其實和回調(diào)是一個概念,當系統(tǒng)執(zhí)行到某處時,檢查是否有 hook(鉤子),有的話就會執(zhí)行回調(diào)。

通俗的說,hook 就是在程序運行中,在某個特定的位置,框架的開發(fā)者設(shè)計好了一個鉤子來告訴我們當前程序已經(jīng)運行到特定的位置了,會觸發(fā)一個回調(diào)函數(shù),并提供給我們,讓我們可以在生命周期的特定階段進行相關(guān)業(yè)務(wù)代碼的編寫。

vue 生命周期有幾個階段

它可以總共分為 8 個階段:創(chuàng)建前/后, 載入前/后,更新前/后,銷毀前/銷毀后。

beforeCreate:是 new Vue( ) 之后觸發(fā)的第一個鉤子,在當前階段 data、methods、computed 以及 watch 上的數(shù)據(jù)和方法都不能被訪問。

created:在實例創(chuàng)建完成后發(fā)生,當前階段已經(jīng)完成了數(shù)據(jù)觀測,也就是可以使用數(shù)據(jù),更改數(shù)據(jù),在這里更改數(shù)據(jù)不會觸發(fā) updated 函數(shù)??梢宰鲆恍┏跏紨?shù)據(jù)的獲取,在當前階段無法與 DOM 進行交互,如果非要想,可以通過 vm.$nextTick 來訪問 DOM 。

beforeMount:發(fā)生在掛載之前,在這之前 template 模板已導(dǎo)入渲染函數(shù)編譯。而當前階段虛擬 DOM 已經(jīng)創(chuàng)建完成,即將開始渲染。在此時也可以對數(shù)據(jù)進行更改,不會觸發(fā) updated。

mounted:在掛載完成后發(fā)生,在當前階段,真實的 DOM 掛載完畢,數(shù)據(jù)完成雙向綁定,可以訪問到 DOM 節(jié)點,使用 $refs 屬性對 DOM 進行操作。

beforeUpdate:發(fā)生在更新之前,也就是響應(yīng)式數(shù)據(jù)發(fā)生更新,虛擬 DOM 重新渲染之前被觸發(fā),你可以在當前階段進行更改數(shù)據(jù),不會造成重渲染。

updated:發(fā)生在更新完成之后,當前階段組件 DOM 已完成更新。要注意的是避免在此期間更改數(shù)據(jù),因為這可能會導(dǎo)致無限循環(huán)的更新。

beforeDestroy:發(fā)生在實例銷毀之前,在當前階段實例完全可以被使用,我們可以在這時進行善后收尾工作,比如清除計時器。

destroyed:發(fā)生在實例銷毀之后,這個時候只剩下了 DOM 空殼。組件已被拆解,數(shù)據(jù)綁定被卸除,監(jiān)聽被移出,子實例也統(tǒng)統(tǒng)被銷毀。

第一次頁面加載會觸發(fā)哪幾個鉤子

會觸發(fā) 4 個鉤子,分別是:beforeCreate、created、beforeMount、mounted

DOM 渲染在哪個周期就已經(jīng)完成

DOM 渲染是在 mounted 階段完成,此階段真實的 DOM 掛載完畢,數(shù)據(jù)完成雙向綁定,可以訪問到 DOM 節(jié)點。

多組件(父子組件)中生命周期的調(diào)用順序說一下

組件的調(diào)用順序都是先父后子,渲染完成的順序是先子后父。組件的銷毀操作是先父后子,銷毀完成的順序是先子后父。

加載渲染過程:父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount- >子mounted->父mounted

子組件更新過程:父beforeUpdate->子beforeUpdate->子updated->父updated

父組件更新過程:父 beforeUpdate -> 父 updated

銷毀過程:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

4. Vue 實現(xiàn)雙向數(shù)據(jù)綁定原理是什么?

Vue2.x 采用數(shù)據(jù)劫持結(jié)合發(fā)布訂閱模式(PubSub 模式)的方式,通過 Object.defineProperty 來劫持各個屬性的 setter、getter,在數(shù)據(jù)變動時發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。

當把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉(zhuǎn)為 getter/setter。用戶看不到 getter/setter,但是在內(nèi)部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。

Vue 的數(shù)據(jù)雙向綁定整合了 Observer,Compile 和 Watcher 三者,通過 Observer 來監(jiān)聽自己的 model 的數(shù)據(jù)變化,通過 Compile 來解析編譯模板指令,最終利用 Watcher 搭起 Observer 和 Compile 之間的通信橋梁,達到數(shù)據(jù)變化->視圖更新,視圖交互變化(例如 input 操作)->數(shù)據(jù) model 變更的雙向綁定效果。

Vue3.x 放棄了 Object.defineProperty ,使用 ES6 原生的 Proxy,來解決以前使用 Object.defineProperty 所存在的一些問題。

5. 說一下對 Vue2.x 響應(yīng)式原理的理解

Vue 在初始化數(shù)據(jù)時,會使用 Object.defineProperty 重新定義 data 中的所有屬性,當頁面使用對應(yīng)屬性時,首先會進行依賴收集(收集當前組件的 watcher),如果屬性發(fā)生變化會通知相關(guān)依賴進行更新操作(發(fā)布訂閱)。

6. 說一下在 Vue2.x 中如何檢測數(shù)組的變化?

Vue2.x 中實現(xiàn)檢測數(shù)組變化的方法,是將數(shù)組的常用方法進行了重寫。

Vue 將 data 中的數(shù)組進行了原型鏈重寫,指向了自己定義的數(shù)組原型方法。這樣當調(diào)用數(shù)組 api 時,可以通知依賴更新。如果數(shù)組中包含著引用類型,會對數(shù)組中的引用類型再次遞歸遍歷進行監(jiān)控。這樣就實現(xiàn)了監(jiān)測數(shù)組變化。

流程:

初始化傳入 data 數(shù)據(jù)執(zhí)行 initData
將數(shù)據(jù)進行觀測 new Observer
將數(shù)組原型方法指向重寫的原型
深度觀察數(shù)組中的引用類型
有兩種情況無法檢測到數(shù)組的變化。

當利用索引直接設(shè)置一個數(shù)組項時,例如 vm.items[indexOfItem] = newValue
當修改數(shù)組的長度時,例如 vm.items.length = newLength
不過這兩種場景都有對應(yīng)的解決方案。

利用索引設(shè)置數(shù)組項的替代方案

//使用該方法進行更新視圖
// vm.$set,Vue.set的一個別名
vm.$set(vm.items, indexOfItem, newValue)

修改數(shù)組的長度的替代方案

//使用該方法進行更新視圖
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)


7. Vue3.x 響應(yīng)式數(shù)據(jù)

Vue3.x 響應(yīng)式數(shù)據(jù)原理是什么?
Proxy 只會代理對象的第一層,那么 Vue3 又是怎樣處理這個問題的呢?
監(jiān)測數(shù)組的時候可能觸發(fā)多次 get/set,那么如何防止觸發(fā)多次呢?
?

Vue3.x 響應(yīng)式數(shù)據(jù)原理是什么?

在 Vue 2 中,響應(yīng)式原理就是使用的 Object.defineProperty 來實現(xiàn)的。但是在 Vue 3.0 中采用了 Proxy,拋棄了 Object.defineProperty 方法。

究其原因,主要是以下幾點:

Object.defineProperty 無法監(jiān)控到數(shù)組下標的變化,導(dǎo)致通過數(shù)組下標添加元素,不能實時響應(yīng)
Object.defineProperty 只能劫持對象的屬性,從而需要對每個對象,每個屬性進行遍歷,如果,屬性值是對象,還需要深度遍歷。Proxy 可以劫持整個對象,并返回一個新的對象。
Proxy 不僅可以代理對象,還可以代理數(shù)組。還可以代理動態(tài)增加的屬性。
Proxy 有多達 13 種攔截方法
Proxy作為新標準將受到瀏覽器廠商重點持續(xù)的性能優(yōu)化
Proxy 只會代理對象的第一層,那么 Vue3 又是怎樣處理這個問題的呢?

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

監(jiān)測數(shù)組的時候可能觸發(fā)多次 get/set,那么如何防止觸發(fā)多次呢?

我們可以判斷 key 是否為當前被代理對象 target 自身屬性,也可以判斷舊值與新值是否相等,只有滿足以上兩個條件之一時,才有可能執(zhí)行 trigger。

8. v-model 雙向綁定的原理是什么?

v-model 本質(zhì)就是 :value + input 方法的語法糖??梢酝ㄟ^ model 屬性的 prop 和 event 屬性來進行自定義。原生的 v-model,會根據(jù)標簽的不同生成不同的事件和屬性。

例如:

text 和 textarea 元素使用 value 屬性和 input 事件
checkbox 和 radio 使用 checked 屬性和 change 事件
select 字段將 value 作為 prop 并將 change 作為事件
以輸入框為例,當用戶在輸入框輸入內(nèi)容時,會觸發(fā) input 事件,從而更新 value。而 value 的改變同樣會更新視圖,這就是 vue 中的雙向綁定。雙向綁定的原理,其實現(xiàn)思路如下:

首先要對數(shù)據(jù)進行劫持監(jiān)聽,所以我們需要設(shè)置一個監(jiān)聽器 Observer,用來監(jiān)聽所有屬性。如果屬性發(fā)上變化了,就需要告訴訂閱者 Watcher 看是否需要更新。

因為訂閱者是有很多個,所以我們需要有一個消息訂閱器 Dep 來專門收集這些訂閱者,然后在監(jiān)聽器 Observer 和訂閱者 Watcher 之間進行統(tǒng)一管理的。

接著,我們還需要有一個指令解析器 Compile,對每個節(jié)點元素進行掃描和解析,將相關(guān)指令對應(yīng)初始化成一個訂閱者 Watcher,并替換模板數(shù)據(jù)或者綁定相應(yīng)的函數(shù),此時當訂閱者 Watcher 接收到相應(yīng)屬性的變化,就會執(zhí)行對應(yīng)的更新函數(shù),從而更新視圖。

因此接下去我們執(zhí)行以下 3 個步驟,實現(xiàn)數(shù)據(jù)的雙向綁定:

實現(xiàn)一個監(jiān)聽器 Observer,用來劫持并監(jiān)聽所有屬性,如果有變動的,就通知訂閱者。

實現(xiàn)一個訂閱者 Watcher,可以收到屬性的變化通知并執(zhí)行相應(yīng)的函數(shù),從而更新視圖。

實現(xiàn)一個解析器 Compile,可以掃描和解析每個節(jié)點的相關(guān)指令,并根據(jù)初始化模板數(shù)據(jù)以及初始化相應(yīng)的訂閱器。


9. vue2.x 和 vuex3.x 渲染器的 diff 算法分別說一下?
?

簡單來說,diff 算法有以下過程

同級比較,再比較子節(jié)點
先判斷一方有子節(jié)點一方?jīng)]有子節(jié)點的情況(如果新的 children 沒有子節(jié)點,將舊的子節(jié)點移除)
比較都有子節(jié)點的情況(核心 diff)
遞歸比較子節(jié)點
正常 Diff 兩個樹的時間復(fù)雜度是 O(n^3),但實際情況下我們很少會進行跨層級的移動 DOM,所以 Vue 將 Diff 進行了優(yōu)化,從O(n^3) -> O(n),只有當新舊 children 都為多個子節(jié)點時才需要用核心的 Diff 算法進行同層級比較。

Vue2 的核心 Diff 算法采用了雙端比較的算法,同時從新舊 children 的兩端開始進行比較,借助 key 值找到可復(fù)用的節(jié)點,再進行相關(guān)操作。相比 React 的 Diff 算法,同樣情況下可以減少移動節(jié)點次數(shù),減少不必要的性能損耗,更加的優(yōu)雅。

Vue3.x 借鑒了 ivi 算法和 inferno 算法

在創(chuàng)建 VNode 時就確定其類型,以及在 mount/patch 的過程中采用位運算來判斷一個 VNode 的類型,在這個基礎(chǔ)之上再配合核心的 Diff 算法,使得性能上較 Vue2.x 有了提升。該算法中還運用了動態(tài)規(guī)劃的思想求解最長遞歸子序列。


10. vue 組件的參數(shù)傳遞

解釋一下父組件與子組件傳值實現(xiàn)過程
非父子組件的數(shù)據(jù)傳遞,兄弟組件傳值是如何實現(xiàn)的
?

解釋一下父組件與子組件傳值實現(xiàn)過程

父組件傳給子組件:子組件通過 props 方法接受數(shù)據(jù)

子組件傳給父組件:使用自定義事件,自組件通過 $emit 方法觸發(fā)父組件的方法來傳遞參數(shù)

非父子組件的數(shù)據(jù)傳遞,兄弟組件傳值是如何實現(xiàn)的

eventBus,就是創(chuàng)建一個事件中心,相當于中轉(zhuǎn)站,可以用它來傳遞事件和接收事件。項目比較小時,用這個比較合適。

此外,總結(jié) vue 中的組件通信方式,常見使用場景可以分為三類:

父子通信:
父向子傳遞數(shù)據(jù)是通過 props ,子向父是通過 $emit / $on
$emit / $bus
vuex
通過父鏈 / 子鏈也可以通信( $parent / $children )
ref 也可以訪問組件實例
v-model
.sync 修飾符
兄弟通信:
$emit / $bus
vuex
跨級通信:
$emit / $bus
vuex
provide / inject API
a t t r s / attrs/attrs/listeners


11. Vue 的路由實現(xiàn)

解釋 hash 模式和 history 模式的實現(xiàn)原理
說一下 r o u t e r ? 與 ? router* 與 *router?與?route 的區(qū)別
vueRouter 有哪幾種導(dǎo)航守衛(wèi)?
解釋一下 vueRouter 的完整的導(dǎo)航解析流程是什么
?

解釋 hash 模式和 history 模式的實現(xiàn)原理

# 后面 hash 值的變化,不會導(dǎo)致瀏覽器向服務(wù)器發(fā)出請求,瀏覽器不發(fā)出請求,就不會刷新頁面;通過監(jiān)聽 hashchange 事件可以知道 hash 發(fā)生了哪些變化,然后根據(jù) hash 變化來實現(xiàn)更新頁面部分內(nèi)容的操作。

history 模式的實現(xiàn),主要是 HTML5 標準發(fā)布的兩個 API,pushState 和 replaceState,這兩個 API 可以在改變 URL,但是不會發(fā)送請求。這樣就可以監(jiān)聽 url 變化來實現(xiàn)更新頁面部分內(nèi)容的操作。

兩種模式的區(qū)別:

首先是在 URL 的展示上,hash 模式有“#”,history 模式?jīng)]有

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

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

說一下 r o u t e r ? 與 ? router* 與 *router?與?route 的區(qū)別

$route 對象表示當前的路由信息,包含了當前 URL 解析得到的信息。包含當前的路徑,參數(shù),query 對象等。

$route.path:字符串,對應(yīng)當前路由的路徑,總是解析為絕對路徑,如 “/foo/bar”。
$route.params: 一個 key/value 對象,包含了 動態(tài)片段 和 全匹配片段,如果沒有路由參數(shù),就是一個空對象。
r o u t e . q u e r y ? :一個 k e y / v a l u e 對象,表示 U R L 查詢參數(shù)。例如對于路徑 ? / f o o ? u s e r = 1 ? ,則有 ? route.query*:一個 key/value 對象,表示 URL 查詢參數(shù)。例如對于路徑 */foo?user=1*,則有 *route.query?:一個key/value對象,表示URL查詢參數(shù)。例如對于路徑?/foo?user=1?,則有?route.query.user == 1,如果沒有查詢參數(shù),則是個空對象。
$route.hash:當前路由的 hash 值 (不帶 #) ,如果沒有 hash 值,則為空字符串。
$route.fullPath:完成解析后的 URL,包含查詢參數(shù)和 hash 的完整路徑。
$route.matched:數(shù)組,包含當前匹配的路徑中所包含的所有片段所對應(yīng)的配置參數(shù)對象。
$route.name:當前路徑名字
$route.meta:路由元信息
$route 對象出現(xiàn)在多個地方:

組件內(nèi)的 this.$route 和 route watcher 回調(diào)(監(jiān)測變化處理)
router.match(location) 的返回值
scrollBehavior 方法的參數(shù)
導(dǎo)航鉤子的參數(shù),例如 router.beforeEach 導(dǎo)航守衛(wèi)的鉤子函數(shù)中,to 和 from 都是這個路由信息對象。
$router 對象是全局路由的實例,是 router 構(gòu)造方法的實例。

$router 對象常用的方法有:

push:向 history 棧添加一個新的記錄
go:頁面路由跳轉(zhuǎn)前進或者后退
replace:替換當前的頁面,不會向 history 棧添加一個新的記錄
vueRouter 有哪幾種導(dǎo)航守衛(wèi)?

全局前置/鉤子:beforeEach、beforeR-esolve、afterEach

路由獨享的守衛(wèi):beforeEnter

組件內(nèi)的守衛(wèi):beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

解釋一下 vueRouter 的完整的導(dǎo)航解析流程是什么

一次完整的導(dǎo)航解析流程如下:

導(dǎo)航被觸發(fā)。
在失活的組件里調(diào)用離開守衛(wèi)。
調(diào)用全局的 beforeEach 守衛(wèi)。
在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi)(2.2+)。
在路由配置里調(diào)用 beforeEnter。
解析異步路由組件。
在被激活的組件里調(diào)用 beforeRouteEnter。
調(diào)用全局的 beforeResolve 守衛(wèi)(2.5+)。
導(dǎo)航被確認。
調(diào)用全局的 afterEach 鉤子。
觸發(fā) DOM 更新。
用創(chuàng)建好的實例調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù)。


12. vuex 是什么?怎么使用它?什么場景下我們會使用到 vuex
?

vuex 是什么

vuex 是一個專為 Vue 應(yīng)用程序開發(fā)的狀態(tài)管理器,采用集中式存儲管理應(yīng)用的所有組件的狀態(tài)。每一個 vuex 應(yīng)用的核心就是 store(倉庫)?!皊tore” 基本上就是一個容器,它包含著應(yīng)用中大部分的狀態(tài) (state)。

為什么需要 vuex

由于組件只維護自身的狀態(tài)(data),組件創(chuàng)建時或者路由切換時,組件會被初始化,從而導(dǎo)致 data 也隨之銷毀。

使用方法

在 main.js 引入 store,注入。只用來讀取的狀態(tài)集中放在 store 中, 改變狀態(tài)的方式是提交 mutations,這是個同步的事物,異步邏輯應(yīng)該封裝在 action 中。

什么場景下會使用到 vuex

如果是 vue 的小型應(yīng)用,那么沒有必要使用 vuex,這個時候使用 vuex 反而會帶來負擔。組件之間的狀態(tài)傳遞使用 props、自定義事件來傳遞即可。

但是如果涉及到 vue 的大型應(yīng)用,那么就需要類似于 vuex 這樣的集中管理狀態(tài)的狀態(tài)機來管理所有組件的狀態(tài)。例如登錄狀態(tài)、加入購物車、音樂播放等,總之只要是開發(fā) vue 的大型應(yīng)用,都推薦使用 vuex 來管理所有組件狀態(tài)。

13. 說一下 v-for 與 v-show 的區(qū)別
?

共同點:都是動態(tài)顯示 DOM 元素

區(qū)別點:

手段

v-if 是動態(tài)的向 DOM 樹內(nèi)添加或者刪除 DOM 元素

v-show 是通過設(shè)置 DOM 元素的 display 樣式屬性控制顯隱

編譯過程

v-if 切換有一個局部編譯/卸載的過程,切換過程中合適地銷毀和重建內(nèi)部的事件監(jiān)聽和子組件

v-show 只是簡單的基于 css 切換

編譯條件

v-if 是惰性的,如果初始條件為假,則什么也不做。只有在條件第一次變?yōu)檎鏁r才開始局部編譯

v-show 是在任何條件下(首次條件是否為真)都被編譯,然后被緩存,而且 DOM 元素保留

性能消耗

v-if 有更高的切換消耗

v-show 有更高的初始渲染消耗

使用場景

v-if 適合運營條件不大可能改變

v-show 適合頻繁切換

14. 如何讓 CSS 值在當前的組件中起作用
?

在 vue 文件中的 style 標簽上,有一個特殊的屬性:scoped。當一個 style 標簽擁有 scoped 屬性時,它的 CSS 樣式就只能作用于當前的組件,也就是說,該樣式只能適用于當前組件元素。通過該屬性,可以使得組件之間的樣式不互相污染。如果一個項目中的所有 style 標簽全部加上了 scoped,相當于實現(xiàn)了樣式的模塊化。

scoped 的實現(xiàn)原理

vue 中的 scoped 屬性的效果主要通過 PostCSS 轉(zhuǎn)譯實現(xiàn)的。PostCSS 給一個組件中的所有 DOM 添加了一個獨一無二的動態(tài)屬性,然后,給 CSS 選擇器額外添加一個對應(yīng)的屬性選擇器來選擇該組件中 DOM,這種做法使得樣式只作用于含有該屬性的 DOM,即組件內(nèi)部 DOM。

例如:

轉(zhuǎn)譯前

<template>
? <div class="example">hi</div>
</template>

<style scoped>
.example {
? color: red;
}
</style>
轉(zhuǎn)譯后:

<template>
? <div class="example" data-v-5558831a>hi</div>
</template>

<style>
.example[data-v-5558831a] {
? color: red;
}
</style>


15. keep-alive 相關(guān)

keep-alive的實現(xiàn)原理是什么
與keep-alive相關(guān)的生命周期函數(shù)是什么,什么場景下會進行使用
keep-alive的常用屬性有哪些
?

keep-alive 組件是 vue 的內(nèi)置組件,用于緩存內(nèi)部組件實例。這樣做的目的在于,keep-alive 內(nèi)部的組件切回時,不用重新創(chuàng)建組件實例,而直接使用緩存中的實例,一方面能夠避免創(chuàng)建組件帶來的開銷,另一方面可以保留組件的狀態(tài)。

keep-alive 具有 include 和 exclude 屬性,通過它們可以控制哪些組件進入緩存。另外它還提供了 max 屬性,通過它可以設(shè)置最大緩存數(shù),當緩存的實例超過該數(shù)時,vue 會移除最久沒有使用的組件緩存。

受keep-alive的影響,其內(nèi)部所有嵌套的組件都具有兩個生命周期鉤子函數(shù),分別是 activated 和 deactivated,它們分別在組件激活和失活時觸發(fā)。第一次 activated 觸發(fā)是在 mounted 之后

在具體的實現(xiàn)上,keep-alive 在內(nèi)部維護了一個 key 數(shù)組和一個緩存對象

// keep-alive 內(nèi)部的聲明周期函數(shù)
created () {
? ? this.cache = Object.create(null)
? ? this.keys = []
}

key 數(shù)組記錄目前緩存的組件 key 值,如果組件沒有指定 key 值,則會為其自動生成一個唯一的 key 值

cache 對象以 key 值為鍵,vnode 為值,用于緩存組件對應(yīng)的虛擬 DOM

在 keep-alive 的渲染函數(shù)中,其基本邏輯是判斷當前渲染的 vnode 是否有對應(yīng)的緩存,如果有,從緩存中讀取到對應(yīng)的組件實例;如果沒有則將其緩存。

當緩存數(shù)量超過 max 數(shù)值時,keep-alive 會移除掉 key 數(shù)組的第一個元素。

16. Vue 中如何進行組件的使用?Vue 如何實現(xiàn)全局組件的注冊?
?

要使用組件,首先需要使用 import 來引入組件,然后在 components 屬性中注冊組件,之后就可以在模板中使用組件了。

可以使用 Vue.component 方法來實現(xiàn)全局組件的注冊。


17. vue-cli 工程相關(guān)

構(gòu)建 vue-cli 工程都用到了哪些技術(shù)?他們的作用分別是什么?
vue-cli 工程常用的 npm 命令有哪些?

構(gòu)建 vue-cli 工程都用到了哪些技術(shù)?他們的作用分別是什么?

vue.js:vue-cli 工程的核心,主要特點是雙向數(shù)據(jù)綁定和組件系統(tǒng)。
vue-router:vue 官方推薦使用的路由框架。
vuex:專為 Vue.js 應(yīng)用項目開發(fā)的狀態(tài)管理器,主要用于維護 vue 組件間共用的一些 變量 和 方法。
axios(或者 fetch、ajax):用于發(fā)起 GET 、或 POST 等 http請求,基于 Promise 設(shè)計。
vux等:一個專為vue設(shè)計的移動端UI組件庫。
webpack:模塊加載和vue-cli工程打包器。
eslint:代碼規(guī)范工具
vue-cli 工程常用的 npm 命令有哪些?

下載 node_modules 資源包的命令:npm install

啟動 vue-cli 開發(fā)環(huán)境的 npm命令:npm run dev

vue-cli 生成 生產(chǎn)環(huán)境部署資源 的 npm命令:npm run build

用于查看 vue-cli 生產(chǎn)環(huán)境部署資源文件大小的 npm命令:npm run build --report

18. nextTick 的作用是什么?他的實現(xiàn)原理是什么?
?

作用:vue 更新 DOM 是異步更新的,數(shù)據(jù)變化,DOM 的更新不會馬上完成,nextTick 的回調(diào)是在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行的延遲回調(diào)。

實現(xiàn)原理:nextTick 主要使用了宏任務(wù)和微任務(wù)。根據(jù)執(zhí)行環(huán)境分別嘗試采用

Promise:可以將函數(shù)延遲到當前函數(shù)調(diào)用棧最末端
MutationObserver :是 H5 新加的一個功能,其功能是監(jiān)聽 DOM 節(jié)點的變動,在所有 DOM 變動完成后,執(zhí)行回調(diào)函數(shù)
setImmediate:用于中斷長時間運行的操作,并在瀏覽器完成其他操作(如事件和顯示更新)后立即運行回調(diào)函數(shù)
如果以上都不行則采用 setTimeout 把函數(shù)延遲到 DOM 更新之后再使用
原因是宏任務(wù)消耗大于微任務(wù),優(yōu)先使用微任務(wù),最后使用消耗最大的宏任務(wù)。

19. 說一下 Vue SSR 的實現(xiàn)原理
?

app.js 作為客戶端與服務(wù)端的公用入口,導(dǎo)出 Vue 根實例,供客戶端 entry 與服務(wù)端 entry 使用??蛻舳?entry 主要作用掛載到 DOM 上,服務(wù)端 entry 除了創(chuàng)建和返回實例,還需要進行路由匹配與數(shù)據(jù)預(yù)獲取。
webpack 為客服端打包一個 ClientBundle,為服務(wù)端打包一個 ServerBundle。
服務(wù)器接收請求時,會根據(jù) url,加載相應(yīng)組件,獲取和解析異步數(shù)據(jù),創(chuàng)建一個讀取 Server Bundle 的 BundleRenderer,然后生成 html 發(fā)送給客戶端。
客戶端混合,客戶端收到從服務(wù)端傳來的 DOM 與自己的生成的 DOM 進行對比,把不相同的 DOM 激活,使其可以能夠響應(yīng)后續(xù)變化,這個過程稱為客戶端激活(也就是轉(zhuǎn)換為單頁應(yīng)用)。為確?;旌铣晒?#xff0c;客戶 端與服務(wù)器端需要共享同一套數(shù)據(jù)。在服務(wù)端,可以在渲染之前獲取數(shù)據(jù),填充到 store 里,這樣,在客戶端掛載到 DOM 之前,可以直接從 store 里取數(shù)據(jù)。首屏的動態(tài)數(shù)據(jù)通過 window._INITIAL_STATE_ 發(fā)送到客戶端
VueSSR 的原理,主要就是通過 vue-server-renderer 把 Vue 的組件輸出成一個完整 HTML,輸出到客戶端,到達客戶端后重新展開為一個單頁應(yīng)用。


20. Vue 組件的 data 為什么必須是函數(shù)
?

組件中的 data 寫成一個函數(shù),數(shù)據(jù)以函數(shù)返回值形式定義。這樣每復(fù)用一次組件,就會返回一份新的 data,類似于給每個組件實例創(chuàng)建一個私有的數(shù)據(jù)空間,讓各個組件實例維護各自的數(shù)據(jù)。而單純的寫成對象形式,就使得所有組件實例共用了一份 data,就會造成一個變了全都會變的結(jié)果。

21. 說一下 Vue 的 computed 的實現(xiàn)原理
?

當組件實例觸發(fā)生命周期函數(shù) beforeCreate 后,它會做一系列事情,其中就包括對 computed 的處理。

它會遍歷 computed 配置中的所有屬性,為每一個屬性創(chuàng)建一個 Watcher 對象,并傳入一個函數(shù),該函數(shù)的本質(zhì)其實就是 computed 配置中的 getter,這樣一來,getter 運行過程中就會收集依賴

但是和渲染函數(shù)不同,為計算屬性創(chuàng)建的 Watcher 不會立即執(zhí)行,因為要考慮到該計算屬性是否會被渲染函數(shù)使用,如果沒有使用,就不會得到執(zhí)行。因此,在創(chuàng)建 Watcher 的時候,它使用了 lazy 配置,lazy 配置可以讓 Watcher 不會立即執(zhí)行。

收到 lazy 的影響,Watcher 內(nèi)部會保存兩個關(guān)鍵屬性來實現(xiàn)緩存,一個是 value,一個是 dirty

value 屬性用于保存 Watcher 運行的結(jié)果,受 lazy 的影響,該值在最開始是 undefined

dirty 屬性用于指示當前的 value 是否已經(jīng)過時了,即是否為臟值,受 lazy 的影響,該值在最開始是 true

Watcher 創(chuàng)建好后,vue 會使用代理模式,將計算屬性掛載到組件實例中

當讀取計算屬性時,vue 檢查其對應(yīng)的 Watcher 是否是臟值,如果是,則運行函數(shù),計算依賴,并得到對應(yīng)的值,保存在 Watcher 的 value 中,然后設(shè)置 dirty 為 false,然后返回。

如果 dirty 為 false,則直接返回 watcher 的 value

巧妙的是,在依賴收集時,被依賴的數(shù)據(jù)不僅會收集到計算屬性的 Watcher,還會收集到組件的 Watcher

當計算屬性的依賴變化時,會先觸發(fā)計算屬性的 Watcher 執(zhí)行,此時,它只需設(shè)置 dirty 為 true 即可,不做任何處理。

由于依賴同時會收集到組件的 Watcher,因此組件會重新渲染,而重新渲染時又讀取到了計算屬性,由于計算屬性目前已為 dirty,因此會重新運行 getter 進行運算

而對于計算屬性的 setter,則極其簡單,當設(shè)置計算屬性時,直接運行 setter 即可。

22. 說一下 Vue complier 的實現(xiàn)原理是什么樣的?
?

在使用 vue 的時候,我們有兩種方式來創(chuàng)建我們的 HTML 頁面,第一種情況,也是大多情況下,我們會使用模板 template 的方式,因為這更易讀易懂也是官方推薦的方法;第二種情況是使用 render 函數(shù)來生成 HTML,它比 template 更接近最終結(jié)果。

complier 的主要作用是解析模板,生成渲染模板的 render, 而 render 的作用主要是為了生成 VNode

complier 主要分為 3 大塊:

parse:接受 template 原始模板,按著模板的節(jié)點和數(shù)據(jù)生成對應(yīng)的 ast
optimize:遍歷 ast 的每一個節(jié)點,標記靜態(tài)節(jié)點,這樣就知道哪部分不會變化,于是在頁面需要更新時,通過 diff 減少去對比這部分DOM,提升性能
generate 把前兩步生成完善的 ast,組成 render 字符串,然后將 render 字符串通過 new Function 的方式轉(zhuǎn)換成渲染函數(shù)


23. vue 如何快速定位那個組件出現(xiàn)性能問題的
?

? timeline ?具。 通過 timeline 來查看每個函數(shù)的調(diào)?時常,定位出哪個函數(shù)的問題,從?能判斷哪個組件出了問題。

24. Proxy 相比 defineProperty 的優(yōu)勢在哪里
?

Vue3.x 改用 Proxy 替代 Object.defineProperty

原因在于 Object.defineProperty 本身存在的一些問題:

Object.defineProperty 只能劫持對象屬性的 getter 和 setter 方法。
Object.definedProperty 不支持數(shù)組(可以監(jiān)聽數(shù)組,不過數(shù)組方法無法監(jiān)聽自己重寫),更準確的說是不支持數(shù)組的各種 API(所以 Vue 重寫了數(shù)組方法。
而相比 Object.defineProperty,Proxy 的優(yōu)點在于:

Proxy 是直接代理劫持整個對象。
Proxy 可以直接監(jiān)聽對象和數(shù)組的變化,并且有多達 13 種攔截方法。
目前,Object.definedProperty 唯一比 Proxy 好的一點就是兼容性,不過 Proxy 新標準也受到瀏覽器廠商重點持續(xù)的性能優(yōu)化當中。

25. Vue 與 Angular 以及 React 的區(qū)別是什么?
?

這種題目是開放性題目,一般是面試過程中面試官口頭來提問,不太可能出現(xiàn)在筆試試卷里面。

關(guān)于 Vue 和其他框架的不同,官方專門寫了一篇文檔,從性能、體積、靈活性等多個方面來進行了說明。

詳細可以參閱:https://cn.vuejs.org/v2/guide/comparison.html

建議面試前通讀一遍該篇文檔,然后進行適當?shù)目偨Y(jié)。

26. 說一下 watch 與 computed 的區(qū)別是什么?以及他們的使用場景分別是什么?
?

區(qū)別:

都是觀察數(shù)據(jù)變化的(相同)
計算屬性將會混入到 vue 的實例中,所以需要監(jiān)聽自定義變量;watch 監(jiān)聽 data 、props 里面數(shù)據(jù)的變化;
computed 有緩存,它依賴的值變了才會重新計算,watch 沒有;
watch 支持異步,computed 不支持;
watch 是一對多(監(jiān)聽某一個值變化,執(zhí)行對應(yīng)操作);computed 是多對一(監(jiān)聽屬性依賴于其他屬性)
watch 監(jiān)聽函數(shù)接收兩個參數(shù),第一個是最新值,第二個是輸入之前的值;
computed 屬性是函數(shù)時,都有 get 和 set 方法,默認走 get 方法,get 必須有返回值(return)
watch 的 參數(shù):

deep:深度監(jiān)聽
immediate :組件加載立即觸發(fā)回調(diào)函數(shù)執(zhí)行
computed 緩存原理:

conputed本質(zhì)是一個惰性的觀察者;當計算數(shù)據(jù)存在于 data 或者 props里時會被警告;

vue 初次運行會對 computed 屬性做初始化處理(initComputed),初始化的時候會對每一個 computed 屬性用 watcher 包裝起來 ,這里面會生成一個 dirty 屬性值為 true;然后執(zhí)行 defineComputed 函數(shù)來計算,計算之后會將 dirty 值變?yōu)?false,這里會根據(jù) dirty 值來判斷是否需要重新計算;如果屬性依賴的數(shù)據(jù)發(fā)生變化,computed 的 watcher 會把 dirty 變?yōu)?true,這樣就會重新計算 computed 屬性的值。

27. scoped 是如何實現(xiàn)樣式穿透的?
?

首先說一下什么場景下需要 scoped 樣式穿透。

在很多項目中,會出現(xiàn)這么一種情況,即:引用了第三方組件,需要在組件中局部修改第三方組件的樣式,而又不想去除 scoped 屬性造成組件之間的樣式污染。此時只能通過特殊的方式,穿透 scoped。

有三種常用的方法來實現(xiàn)樣式穿透。

方法一

使用 ::v-deep 操作符( >>> 的別名)

如果希望 scoped 樣式中的一個選擇器能夠作用得“更深”,例如影響子組件,可以使用 >>> 操作符:

<style scoped>
? ? .a >>> .b { /* ... */ }
</style>

上述代碼將會編譯成:

.a[data-v-f3f3eg9] .b { /* ... */ }
后面的類名沒有 data 屬性,所以能選到子組件里面的類名。

有些像 Sass 之類的預(yù)處理器無法正確解析 >>>,所以需要使用 ::v-deep 操作符來代替。

方法二

定義一個含有 scoped 屬性的 style 標簽之外,再定義一個不含有 scoped 屬性的 style 標簽,即在一個 vue 組件中定義一個全局的 style 標簽,一個含有作用域的 style 標簽:

<style>
/* global styles */
</style>

<style scoped>
/* local styles */
</style>
此時,我們只需要將修改第三方樣式的 css 寫在第一個 style 中即可。

方法三

上面的方法一需要單獨書寫一個不含有 scoped 屬性的 style 標簽,可能會造成全局樣式的污染。

更推薦的方式是在組件的外層 DOM 上添加唯一的 class 來區(qū)分不同組件,在書寫樣式時就可以正常針對針對這部分 DOM 書寫樣式。

28. 說一下 ref 的作用是什么?
?

ref 的作用是被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $refs 對象上。其特點是:

如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素
如果用在子組件上,引用就指向組件實例
所以常見的使用場景有:

基本用法,本頁面獲取 DOM 元素
獲取子組件中的 data
調(diào)用子組件中的方法


29. 說一下你知道的 vue 修飾符都有哪些?
?

在 vue 中修飾符可以分為 3 類:

事件修飾符
按鍵修飾符
表單修飾符
事件修飾符

在事件處理程序中調(diào)用 event.preventDefault 或 event.stopPropagation 方法是非常常見的需求。盡管可以在 methods 中輕松實現(xiàn)這點,但更好的方式是:methods 只有純粹的數(shù)據(jù)邏輯,而不是去處理 DOM 事件細節(jié)。

為了解決這個問題,vue 為 v-on 提供了事件修飾符。通過由點 . 表示的指令后綴來調(diào)用修飾符。

常見的事件修飾符如下:

.stop:阻止冒泡。
.prevent:阻止默認事件。
.capture:使用事件捕獲模式。
.self:只在當前元素本身觸發(fā)。
.once:只觸發(fā)一次。
.passive:默認行為將會立即觸發(fā)。
按鍵修飾符

除了事件修飾符以外,在 vue 中還提供了有鼠標修飾符,鍵值修飾符,系統(tǒng)修飾符等功能。

.left:左鍵
.right:右鍵
.middle:滾輪
.enter:回車
.tab:制表鍵
.delete:捕獲 “刪除” 和 “退格” 鍵
.esc:返回
.space:空格
.up:上
.down:下
.left:左
.right:右
.ctrl:ctrl 鍵
.alt:alt 鍵
.shift:shift 鍵
.meta:meta 鍵
表單修飾符

vue 同樣也為表單控件也提供了修飾符,常見的有 .lazy、.number 和 .trim。

.lazy:在文本框失去焦點時才會渲染
.number:將文本框中所輸入的內(nèi)容轉(zhuǎn)換為number類型
.trim:可以自動過濾輸入首尾的空格


30. 如何實現(xiàn) vue 項目中的性能優(yōu)化?
?

編碼階段

盡量減少 data 中的數(shù)據(jù),data 中的數(shù)據(jù)都會增加 getter 和 setter,會收集對應(yīng)的 watcher
v-if 和 v-for 不能連用
如果需要使用 v-for 給每項元素綁定事件時使用事件代理
SPA 頁面采用 keep-alive 緩存組件
在更多的情況下,使用 v-if 替代 v-show
key 保證唯一
使用路由懶加載、異步組件
防抖、節(jié)流
第三方模塊按需導(dǎo)入
長列表滾動到可視區(qū)域動態(tài)加載
圖片懶加載
SEO 優(yōu)化

預(yù)渲染
服務(wù)端渲染 SSR
打包優(yōu)化

壓縮代碼
Tree Shaking/Scope Hoisting
使用 cdn 加載第三方模塊
多線程打包 happypack
splitChunks 抽離公共文件
sourceMap 優(yōu)化
用戶體驗

骨架屏
PWA
還可以使用緩存(客戶端緩存、服務(wù)端緩存)優(yōu)化、服務(wù)端開啟 gzip 壓縮等。

31. Vue.extend 和 Vue.component 的區(qū)別是什么?
?

Vue.extend 用于創(chuàng)建一個基于 Vue 構(gòu)造函數(shù)的“子類”,其參數(shù)應(yīng)為一個包含組件選項的對象。

Vue.component 用來注冊全局組件。

32. vue 中的 spa 應(yīng)用如何優(yōu)化首屏加載速度?
?

優(yōu)化首屏加載可以從這幾個方面開始:

請求優(yōu)化:CDN 將第三方的類庫放到 CDN 上,能夠大幅度減少生產(chǎn)環(huán)境中的項目體積,另外 CDN 能夠?qū)崟r地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點的連接、負載狀況以及到用戶的距離和響應(yīng)時間等綜合信息將用戶的請求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點上。
緩存:將長時間不會改變的第三方類庫或者靜態(tài)資源設(shè)置為強緩存,將 max-age 設(shè)置為一個非常長的時間,再將訪問路徑加上哈希達到哈希值變了以后保證獲取到最新資源,好的緩存策略有助于減輕服務(wù)器的壓力,并且顯著的提升用戶的體驗
gzip:開啟 gzip 壓縮,通常開啟 gzip 壓縮能夠有效的縮小傳輸資源的大小。
http2:如果系統(tǒng)首屏同一時間需要加載的靜態(tài)資源非常多,但是瀏覽器對同域名的 tcp 連接數(shù)量是有限制的(chrome 為 6 個)超過規(guī)定數(shù)量的 tcp 連接,則必須要等到之前的請求收到響應(yīng)后才能繼續(xù)發(fā)送,而 http2 則可以在多個 tcp 連接中并發(fā)多個請求沒有限制,在一些網(wǎng)絡(luò)較差的環(huán)境開啟 http2 性能提升尤為明顯。
懶加載:當 url 匹配到相應(yīng)的路徑時,通過 import 動態(tài)加載頁面組件,這樣首屏的代碼量會大幅減少,webpack 會把動態(tài)加載的頁面組件分離成單獨的一個 chunk.js 文件
預(yù)渲染:由于瀏覽器在渲染出頁面之前,需要先加載和解析相應(yīng)的 html、css 和 js 文件,為此會有一段白屏的時間,可以添加loading,或者骨架屏幕盡可能的減少白屏對用戶的影響體積優(yōu)化
合理使用第三方庫:對于一些第三方 ui 框架、類庫,盡量使用按需加載,減少打包體積
使用可視化工具分析打包后的模塊體積:webpack-bundle- analyzer 這個插件在每次打包后能夠更加直觀的分析打包后模塊的體積,再對其中比較大的模塊進行優(yōu)化
提高代碼使用率:利用代碼分割,將腳本中無需立即調(diào)用的代碼在代碼構(gòu)建時轉(zhuǎn)變?yōu)楫惒郊虞d的過程
封裝:構(gòu)建良好的項目架構(gòu),按照項目需求就行全局組件,插件,過濾器,指令,utils 等做一 些公共封裝,可以有效減少我們的代碼量,而且更容易維護資源優(yōu)化
圖片懶加載:使用圖片懶加載可以優(yōu)化同一時間減少 http 請求開銷,避免顯示圖片導(dǎo)致的畫面抖動,提高用戶體驗
使用 svg 圖標:相對于用一張圖片來表示圖標,svg 擁有更好的圖片質(zhì)量,體積更小,并且不需要開啟額外的 http 請求
壓縮圖片:可以使用 image-webpack-loader,在用戶肉眼分辨不清的情況下一定程度上壓縮圖片


33. 移動端如何實現(xiàn)一個比較友好的 header 組件
?

Header 一般分為左、中、右三個部分,分為三個區(qū)域來設(shè)計,中間為主標題,每個頁面的標題肯定不同,所以可以通過 vue props的方式做成可配置對外進行暴露,左側(cè)大部分頁面可能都是回退按鈕,但是樣式和內(nèi)容不盡相同,右側(cè)一般都是具有功能性的操作按鈕,所以左右兩側(cè)可以通過 vue slot 插槽的方式對外暴露以實現(xiàn)多樣化,同時也可以提供 default slot 默認插槽來統(tǒng)一頁面風(fēng)格。

34. 既然 Vue 通過數(shù)據(jù)劫持可以精準探測數(shù)據(jù)變化,為什么還需要虛擬 DOM 進行 diff 監(jiān)測差異 ?
?

現(xiàn)代前端框架有兩種方式偵測變化,一種是 pull,一種是 push。

pull

其代表為 React,我們可以回憶一下 React 是如何偵測到變化的。

我們通常會用 setState API 顯式更新,然后 React 會進行一層層的 Virtual Dom Diff 操作找出差異,然后 Patch 到 DOM 上,React 從一開始就不知道到底是哪發(fā)生了變化,只是知道「有變化了」,然后再進行比較暴力的 Diff 操作查找「哪發(fā)生變化了」,另外一個代表就是 Angular 的臟檢查操作。

push

Vue 的響應(yīng)式系統(tǒng)則是 push 的代表,當 Vue 程序初始化的時候就會對數(shù)據(jù) data 進行依賴的收集,一但數(shù)據(jù)發(fā)生變化,響應(yīng)式系統(tǒng)就會立刻得知,因此 Vue 是一開始就知道是「在哪發(fā)生變化了」

但是這又會產(chǎn)生一個問題,通常綁定一個數(shù)據(jù)就需要一個 Watcher,一但我們的綁定細粒度過高就會產(chǎn)生大量的 Watcher,這會帶來內(nèi)存以及依賴追蹤的開銷,而細粒度過低會無法精準偵測變化,因此 Vue 的設(shè)計是選擇中等細粒度的方案,在組件級別進行 push 偵測的方式,也就是那套響應(yīng)式系統(tǒng)。

通常我們會第一時間偵測到發(fā)生變化的組件,然后在組件內(nèi)部進行 Virtual Dom Diff 獲取更加具體的差異,而 Virtual Dom Diff 則是 pull 操作,Vue 是 push + pull 結(jié)合的方式進行變化偵測的。

35. Vue 為什么沒有類似于 React 中 shouldComponentUpdate 的生命周期?
?

根本原因是 Vue 與 React 的變化偵測方式有所不同

React 是 pull 的方式偵測變化,當 React 知道發(fā)生變化后,會使用 Virtual Dom Diff 進行差異檢測,但是很多組件實際上是肯定不會發(fā)生變化的,這個時候需要用 shouldComponentUpdate 進行手動操作來減少 diff,從而提高程序整體的性能。

Vue 是 pull+push 的方式偵測變化的,在一開始就知道那個組件發(fā)生了變化,因此在 push 的階段并不需要手動控制 diff,而組件內(nèi)部采用的 diff 方式實際上是可以引入類似于 shouldComponentUpdate 相關(guān)生命周期的,但是通常合理大小的組件不會有過量的 diff,手動優(yōu)化的價值有限,因此目前 Vue 并沒有考慮引入 shouldComponentUpdate 這種手動優(yōu)化的生命周期。

36. Vue 中的 Key 的作用是什么?

key 的作用主要是為了高效的更新虛擬 DOM。另外 vue 中在使用相同標簽名元素的過渡切換時,也會使用到 key 屬性,其目的也是為了讓 vue 可以區(qū)分它們,否則 vue 只會替換其內(nèi)部屬性而不會觸發(fā)過渡效果。

解析:

其實不只是 vue,react 中在執(zhí)行列表渲染時也會要求給每個組件添加上 key 這個屬性。

要解釋 key 的作用,不得不先介紹一下虛擬 DOM 的 Diff 算法了。

我們知道,vue 和 react 都實現(xiàn)了一套虛擬 DOM,使我們可以不直接操作 DOM 元素,只操作數(shù)據(jù)便可以重新渲染頁面。而隱藏在背后的原理便是其高效的 Diff 算法。

vue 和 react 的虛擬 DOM 的 Diff 算法大致相同,其核心有以下兩點:

兩個相同的組件產(chǎn)生類似的 DOM 結(jié)構(gòu),不同的組件產(chǎn)生不同的 DOM 結(jié)構(gòu)。

同一層級的一組節(jié)點,他們可以通過唯一的 id 進行區(qū)分。

基于以上這兩點,使得虛擬 DOM 的 Diff 算法的復(fù)雜度從 O(n^3) 降到了 O(n)。


當頁面的數(shù)據(jù)發(fā)生變化時,Diff 算法只會比較同一層級的節(jié)點:

如果節(jié)點類型不同,直接干掉前面的節(jié)點,再創(chuàng)建并插入新的節(jié)點,不會再比較這個節(jié)點以后的子節(jié)點了。
如果節(jié)點類型相同,則會重新設(shè)置該節(jié)點的屬性,從而實現(xiàn)節(jié)點的更新。
當某一層有很多相同的節(jié)點時,也就是列表節(jié)點時,Diff 算法的更新過程默認情況下也是遵循以上原則。

比如一下這個情況:

我們希望可以在 B 和 C 之間加一個 F,Diff 算法默認執(zhí)行起來是這樣的:

即把 C 更新成 F,D 更新成 C,E 更新成 D,最后再插入 E

是不是很沒有效率?

所以我們需要使用 key 來給每個節(jié)點做一個唯一標識,Diff 算法就可以正確的識別此節(jié)點,找到正確的位置區(qū)插入新的節(jié)點。

37. 你的接口請求一般放在哪個生命周期中?為什么要這樣做?

接口請求可以放在鉤子函數(shù) created、beforeMount、mounted 中進行調(diào)用,因為在這三個鉤子函數(shù)中,data 已經(jīng)創(chuàng)建,可以將服務(wù)端端返回的數(shù)據(jù)進行賦值。

但是推薦在 created 鉤子函數(shù)中調(diào)用異步請求,因為在 created 鉤子函數(shù)中調(diào)用異步請求有以下優(yōu)點:

能更快獲取到服務(wù)端數(shù)據(jù),減少頁面 loading 時間
SSR 不支持 beforeMount 、mounted 鉤子函數(shù),所以放在 created 中有助于代碼的一致性
created 是在模板渲染成 html 前調(diào)用,即通常初始化某些屬性值,然后再渲染成視圖。如果在 mounted 鉤子函數(shù)中請求數(shù)據(jù)可能導(dǎo)致頁面閃屏問題


38. 說一下你對 vue 事件綁定原理的理解?
?

vue 中的事件綁定是有兩種,一種是原生的事件綁定,另一種是組件的事件綁定。

原生的事件綁定在普通元素上是通過 @click 進行綁定,在組件上是通過 @click.native 進行綁定,組件中的 nativeOn 是等價于 on 的。組件的事件綁定的 @click 是 vue 中自定義的 $on 方法來實現(xiàn)的,必須有 $emit 才可以觸發(fā)。

原生事件綁定原理

在 runtime下的patch.js中createPatchFunction執(zhí)行了之后再賦值給patch。

createPatchFunction方法有兩個參數(shù),分別是nodeOps存放操作dom節(jié)點的方法和modules,modules是有兩個數(shù)組拼接起來的,modules拼接完的數(shù)組中有一個元素就是events,事件添加就發(fā)生在這里。

events元素關(guān)聯(lián)的就是events.js文件,在events中有一個updateDOMListeners方法,在events文件的結(jié)尾導(dǎo)出了一個對象,然后對象有一個屬性叫做create,這個屬性關(guān)聯(lián)的就是updateDOMListeners方法。

在執(zhí)行createPatchFunction方法時,就會將這兩個參數(shù)傳入,在createPatchFunction方法中接收了一個參數(shù)backend,在該方法中一開始進行backend的解構(gòu),就是上面的nodeOps和modules參數(shù),解構(gòu)完之后進入for循環(huán)。

在createPatchFunction開頭定義了一個cbs對象。for循環(huán)遍歷一個叫hooks的數(shù)組。hooks是文件一開頭定義的一個數(shù)組,其中包括有create,for循環(huán)就是在cbs上定義一系列和hooks元素相同的屬性,然后鍵值是一個數(shù)組,然后數(shù)組內(nèi)容是modules里面的一些內(nèi)容。這時就把events文件中導(dǎo)出來的create屬性放在了cbs上。

當我們進入首次渲染的時候,會執(zhí)行到patch函數(shù)里面的createElm方法,這個方法中就會調(diào)用invokeCreateHooks函數(shù),用來處理事件系統(tǒng),這里就是真正準備進行原生事件綁定的入口。invokeCreateHooks方法中,遍歷了cbs.create數(shù)組里面的內(nèi)容。然后把cbs.create里面的函數(shù)全部都執(zhí)行一次,在cbs.create其中一個函數(shù)就是updateDOMListeners。

updateDOMListeners就是用來添加事件的方法,在這方法中會根據(jù)vnode判斷是否有定義一個點擊事件。如果沒有點擊事件就return。有的話就繼續(xù)執(zhí)行,給on進行賦值,然后進行一些賦值操作,將vnode.elm賦值給target,elm這個屬性就是指向vnode所對應(yīng)的真實dom節(jié)點,這里就是把我們要綁定事件的dom結(jié)點進行緩存,接下來執(zhí)行updateListeners方法。在接下來執(zhí)行updateListeners方法中調(diào)用了一個add的方法,然后在app方法中通過原生addEventListener把事件綁定到dom上。

組件事件綁定原理

在組件實例初始化會調(diào)用initMixin方法中的Vue.prototype._init,在init函數(shù)中,會通過initInternalComponent方法初始化組件信息,將自定義的組件事件放到_parentListeners上,下來就會調(diào)用initEvents來初始化組件事件,在initEvents中會實例上添加一個 _event對象,用于保存自定義事件,然后獲取到 父組件給 子組件綁定的自定義事件,也就是剛才在初始化組件信息的時候?qū)⒆远x的組件事件放在了_parentListeners上,這時候vm.$options._parentListeners就是自定義的事件。

最后進行判斷,如果有自定義的組件事件就執(zhí)行updateComponentListeners方法進行事件綁定,在updateComponentListeners方法中會調(diào)用updateListeners方法,并傳傳一個add方法進行執(zhí)行,這個add方法里就是$on方法。

39. 說一下 vue 模版編譯的原理是什么
?

簡單說,Vue 的編譯過程就是將 template 轉(zhuǎn)化為 render 函數(shù)的過程。會經(jīng)歷以下階段:

生成 AST 樹
優(yōu)化
codegen
首先解析模版,生成 AST 語法樹(一種用 JavaScript 對象的形式來描述整個模板)。 使用大量的正則表達式對模板進行解析,遇到標簽、文本的時候都會執(zhí)行對應(yīng)的鉤子進行相關(guān)處理。

Vue 的數(shù)據(jù)是響應(yīng)式的,但其實模板中并不是所有的數(shù)據(jù)都是響應(yīng)式的。有一些數(shù)據(jù)首次渲染后就不會再變化,對應(yīng)的 DOM 也不會變化。那么優(yōu)化過程就是深度遍歷 AST 樹,按照相關(guān)條件對樹節(jié)點進行標記。這些被標記的節(jié)點(靜態(tài)節(jié)點)我們就可以跳過對它們的比對,對運行時的模板起到很大的優(yōu)化作用。

編譯的最后一步是將優(yōu)化后的 AST 樹轉(zhuǎn)換為可執(zhí)行的代碼。

可以參閱前面第 22 題。

40. delete 和 Vue.delete 刪除數(shù)組的區(qū)別是什么?
?

delete 只是被刪除的元素變成了 empty/undefined 其他的元素的鍵值還是不變。
Vue.delete 是直接將元素從數(shù)組中完全刪除,改變了數(shù)組其他元素的鍵值。

41. v-on 可以實現(xiàn)監(jiān)聽多個方法么?
?

可以監(jiān)聽多個方法。關(guān)于監(jiān)聽多個方法提供了幾種不同的寫法:

寫法一:<div v-on="{ 事件類型: 事件處理函數(shù), 事件類型: 事件處理函數(shù) }"></div>
寫法二:<div @事件類型=“事件處理函數(shù)” @事件類型=“事件處理函數(shù)”></div>
寫法三:在一個事件里面書寫多個事件處理函數(shù)
<div @事件類型=“事件處理函數(shù)1,事件處理函數(shù)2”></div>
寫法四:在事件處理函數(shù)內(nèi)部調(diào)用其他的函數(shù)
示例代碼如下:

<template>
? <div>
? ? <!-- v-on在vue2.x中測試,以下兩種均可-->
? ? <button v-on="{ mouseenter: onEnter, mouseleave: onLeave }">
? ? ? 鼠標進來1
? ? </button>
? ? <button @mouseenter="onEnter" @mouseleave="onLeave">鼠標進來2</button>

? ? <!-- 一個事件綁定多個函數(shù),按順序執(zhí)行,這里分隔函數(shù)可以用逗號也可以用分號-->
? ? <button @click="a(), b()">點我ab</button>
? ? <button @click="one()">點我onetwothree</button>
? </div>
</template>
<script>
export default {
? methods: {
? ? //這里是es6對象里函數(shù)寫法
? ? a() {
? ? ? console.log("a");
? ? },
? ? b() {
? ? ? console.log("b");
? ? },
? ? one() {
? ? ? console.log("one");
? ? ? this.two();
? ? ? this.three();
? ? },
? ? two() {
? ? ? console.log("two");
? ? },
? ? three() {
? ? ? console.log("three");
? ? },
? ? onEnter() {
? ? ? console.log("mouse enter");
? ? },
? ? onLeave() {
? ? ? console.log("mouse leave");
? ? },
? },
};
</script>



42. vue 的數(shù)據(jù)為什么頻繁變化但只會更新一次?
?

這是因為 vue 的 DOM 更新是一個異步操作,在數(shù)據(jù)更新后會首先被 set 鉤子監(jiān)聽到,但是不會馬上執(zhí)行 DOM 更新,而是在下一輪循環(huán)中執(zhí)行更新。

具體實現(xiàn)是 vue 中實現(xiàn)了一個 queue 隊列用于存放本次事件循環(huán)中的所有 watcher 更新,并且同一個 watcher 的更新只會被推入隊列一次,并在本輪事件循環(huán)的微任務(wù)執(zhí)行結(jié)束后執(zhí)行此更新(UI Render 階段),這就是 DOM 只會更新一次的原因。

這種在緩沖時去除重復(fù)數(shù)據(jù)對于避免不必要的計算和 DOM 操作是非常重要的。然后,在下一個的事件循環(huán)“tick”中,vue 刷新隊列并執(zhí)行實際 (已去重的) 工作。vue 在內(nèi)部對異步隊列嘗試使用原生的 Promise.then、MutationObserver 和 setImmediate,如果執(zhí)行環(huán)境不支持,則會采用 setTimeout(fn, 0) 代替。

43. 說一下 vue 中 computed 和 methods 的區(qū)別是什么?
?

首先從表現(xiàn)形式上面來看, computed 和 methods 的區(qū)別大致有下面 4 點:

在使用時,computed 當做屬性使用,而 methods 則當做方法調(diào)用
computed 可以具有 getter 和 setter,因此可以賦值,而 methods 不行
computed 無法接收多個參數(shù),而 methods 可以
computed 具有緩存,而 methods 沒有
而如果從底層來看的話, computed 和 methods 在底層實現(xiàn)上面還有很大的區(qū)別。

vue 對 methods 的處理比較簡單,只需要遍歷 methods 配置中的每個屬性,將其對應(yīng)的函數(shù)使用 bind 綁定當前組件實例后復(fù)制其引用到組件實例中即可

而 vue 對 computed 的處理會稍微復(fù)雜一些。

具體可以參閱前面第 21 題。

44. 在 Vue 中要獲取當前時間你會放到 computed 還是 methods 里?(抖音直播)
?

放在 computed 里面。因為 computed 只有在它的相關(guān)依賴發(fā)生改變時才會重新求值。相比而言,方法只要發(fā)生重新渲染,methods 調(diào)用總會執(zhí)行所有函數(shù)。

45. 在給 vue 中的元素設(shè)置 key 值時可以使用 Math 的 random 方法么?
?

random 是生成隨機數(shù),有一定概率多個 item 會生成相同的值,不能保證唯一。

如果是根據(jù)數(shù)據(jù)來生成 item,數(shù)據(jù)具有 id 屬性,那么就可以使用 id 來作為 key。

如果不是根據(jù)數(shù)據(jù)生成 item,那么最好的方式就是使用時間戳來作為 key。或者使用諸如 uuid 之類的庫來生成唯一的 id。

46. 插槽與作用域插槽的區(qū)別是什么?

插槽的作用是子組件提供了可替換模板,父組件可以更換模板的內(nèi)容。

作用域插槽給了子組件將數(shù)據(jù)返給父組件的能力,子組件一樣可以復(fù)用,同時父組件也可以重新組織內(nèi)容和樣式。

47. vue 中相同邏輯如何進行抽離?

可以使用 vue 里面的混入(mixin)技術(shù)?;烊?#xff08;mixin)提供了一種非常靈活的方式,來將 vue 中相同的業(yè)務(wù)邏輯進行抽離。

例如:

在 data 中有很多是公用數(shù)據(jù)
引用封裝好的組件也都是一樣的
methods、watch、computed 中也都有大量的重復(fù)代碼
當然這個時候可以將所有的代碼重復(fù)去寫來實現(xiàn)功能,但是我們并不不推薦使用這種方式,無論是工作量、工作效率和后期維護來說都是不建議的,這個時候 mixin 就可以大展身手了。

一個混入對象可以包含任意組件選項。當組件使用混入對象時,所有混入對象的選項將被“混合”進入該組件本身的選項。說白了就是給每個生命周期,函數(shù)等等中間加入一些公共邏輯。

混入技術(shù)特點

當組件和混入對象含有同名選項時,這些選項將以恰當?shù)姆绞竭M行“合并”。比如,數(shù)據(jù)對象在內(nèi)部會進行遞歸合并,并在發(fā)生沖突時以組件數(shù)據(jù)優(yōu)先。
同名鉤子函數(shù)將合并為一個數(shù)組,因此都將被調(diào)用。另外,混入對象的鉤子將在組件自身鉤子之前調(diào)用。
值為對象的選項,例如 methods、components 和 directives,將被合并為同一個對象。兩個對象鍵名沖突時,取組件對象的鍵值對。


48. 如何監(jiān)聽 pushstate 和 replacestate 的變化呢?
?

History.replaceState 和 pushState 不會觸發(fā) popstate 事件,所以我們可以通過在方法中創(chuàng)建一個新的全局事件來實現(xiàn) pushstate 和 replacestate 變化的監(jiān)聽。

具體做法為:

var _wr = function(type) {
? var orig = history[type];
? return function() {
? ? ? var rv = orig.apply(this, arguments);
? ? ?var e = new Event(type);
? ? ? e.arguments = arguments;
? ? ? window.dispatchEvent(e);
? ? ? return rv;
? };
};
history.pushState = _wr('pushState');
history.replaceState = _wr('replaceState');

這樣就創(chuàng)建了 2 個全新的事件,事件名為 pushState 和 replaceState,我們就可以在全局監(jiān)聽:

window.addEventListener('replaceState', function(e) {
?console.log('THEY DID IT AGAIN! replaceState 111111');
});
window.addEventListener('pushState', function(e) {
?console.log('THEY DID IT AGAIN! pushState 2222222');
});

這樣就可以監(jiān)聽到 pushState 和 replaceState 行為。

49. 說一下 vue3.0 是如何變得更快的?
?

優(yōu)化 Diff 算法

相比 Vue 2,Vue 3 采用了更加優(yōu)化的渲染策略。去掉不必要的虛擬 DOM 樹遍歷和屬性比較,因為這在更新期間往往會產(chǎn)生最大的性能開銷。

這里有三個主要的優(yōu)化:

首先,在 DOM 樹級別。
在沒有動態(tài)改變節(jié)點結(jié)構(gòu)的模板指令(例如 v-if 和 v-for)的情況下,節(jié)點結(jié)構(gòu)保持完全靜態(tài)。

當更新節(jié)點時,不再需要遞歸遍歷 DOM 樹。所有的動態(tài)綁定部分將在一個平面數(shù)組中跟蹤。這種優(yōu)化通過將需要執(zhí)行的樹遍歷量減少一個數(shù)量級來規(guī)避虛擬 DOM 的大部分開銷。

其次,編譯器積極地檢測模板中的靜態(tài)節(jié)點、子樹甚至數(shù)據(jù)對象,并在生成的代碼中將它們提升到渲染函數(shù)之外。這樣可以避免在每次渲染時重新創(chuàng)建這些對象,從而大大提高內(nèi)存使用率并減少垃圾回收的頻率。

第三,在元素級別。

編譯器還根據(jù)需要執(zhí)行的更新類型,為每個具有動態(tài)綁定的元素生成一個優(yōu)化標志。

例如,具有動態(tài)類綁定和許多靜態(tài)屬性的元素將收到一個標志,提示只需要進行類檢查。運行時將獲取這些提示并采用專用的快速路徑。

綜合起來,這些技術(shù)大大改進了渲染更新基準,Vue 3.0 有時占用的 CPU 時間不到 Vue 2 的十分之一。

體積變小

重寫后的 Vue 支持了 tree-shaking,像修剪樹葉一樣把不需要的東西給修剪掉,使 Vue 3.0 的體積更小。

需要的模塊才會打入到包里,優(yōu)化后的 Vue 3.0 的打包體積只有原來的一半(13kb)。哪怕把所有的功能都引入進來也只有 23kb,依然比 Vue 2.x 更小。像 keep-alive、transition 甚至 v-for 等功能都可以按需引入。

并且 Vue 3.0 優(yōu)化了打包方法,使得打包后的 bundle 的體積也更小。

官方所給出的一份驚艷的數(shù)據(jù):打包大小減少 41%,初次渲染快 55%,更新快 133%,內(nèi)存使用減少 54%。

50. 說一說自定義指令有哪些生命周期?

?

自定義指令的生命周期,有 5 個事件鉤子,可以設(shè)置指令在某一個事件發(fā)生時的具體行為:

bind: 只調(diào)用一次,指令第一次綁定到元素時調(diào)用,用這個鉤子函數(shù)可以定義一個在綁定時執(zhí)行一次的初始化動作。
inserted: 被綁定元素插入父節(jié)點時調(diào)用(父節(jié)點存在即可調(diào)用,不必存在于 document 中)。
update: 被綁定元素所在的模板更新時調(diào)用,而不論綁定值是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新(詳細的鉤子函數(shù)參數(shù)見下)。
componentUpdated: 被綁定元素所在模板完成一次更新周期時調(diào)用。
unbind: 只調(diào)用一次, 指令與元素解綁時調(diào)用。
鉤子函數(shù)的參數(shù) (包括 el,binding,vnode,oldVnode)

el: 指令所綁定的元素,可以用來直接操作 DOM 。
binding: 一個對象,包含以下屬性:name: 指令名、value: 指令的綁定值、oldValue: 指令綁定的前一個值、expression: 綁定值的字符串形式、arg: 傳給指令的參數(shù)、modifiers: 一個包含修飾符的對象。
vnode: Vue 編譯生成的虛擬節(jié)點。
oldVnode: 上一個虛擬節(jié)點,僅在 update 和 componentUpdated 鉤子中可用。


51. 說一說相比 vue3.x 對比 vue2.x 變化
?

源碼組織方式變化:使用 TS 重寫
支持 Composition API:基于函數(shù)的API,更加靈活組織組件邏輯(vue2用的是options api)
響應(yīng)式系統(tǒng)提升:Vue3中響應(yīng)式數(shù)據(jù)原理改成proxy,可監(jiān)聽動態(tài)新增刪除屬性,以及數(shù)組變化
編譯優(yōu)化:vue2通過標記靜態(tài)根節(jié)點優(yōu)化diff,Vue3 標記和提升所有靜態(tài)根節(jié)點,diff的時候只需要對比動態(tài)節(jié)點內(nèi)容
打包體積優(yōu)化:移除了一些不常用的api(inline-template、filter)
生命周期的變化:使用setup代替了之前的beforeCreate和created
Vue3 的 template 模板支持多個根標簽
Vuex狀態(tài)管理:創(chuàng)建實例的方式改變,Vue2為new Store , Vue3為createStore
Route 獲取頁面實例與路由信息:vue2通過this獲取router實例,vue3通過使用 getCurrentInstance/ userRoute和userRouter方法獲取當前組件實例
Props 的使用變化:vue2 通過 this 獲取 props 里面的內(nèi)容,vue3 直接通過 props
父子組件傳值:vue3 在向父組件傳回數(shù)據(jù)時,如使用的自定義名稱,如 backData,則需要在 emits 中定義一下


52. vue 為什么采用異步渲染

因為如果不采用異步更新,那么每次更新數(shù)據(jù)都會對當前組件進行重新渲染;所以為了性能考慮,Vue 會在本輪數(shù)據(jù)更新后,再去異步更新視圖。

異步渲染的原理:

調(diào)用 notify( ) 方法,通知 watcher 進行更新操作
依次調(diào)用 watcher 的 update 方法
對 watcher 進行去重操作(通過id)放到隊列里
執(zhí)行完后異步清空這個隊列,nextTick(flushSchedulerQueue)進行批量更新操作


53. 組件中寫 name 選項有哪些好處
?

可以通過名字找到對應(yīng)的組件( 遞歸組件:組件自身調(diào)用自身 )
可以通過 name 屬性實現(xiàn)緩存功能(keep-alive)
可以通過 name 來識別組件(跨級組件通信時非常重要)
使用 vue-devtools 調(diào)試工具里顯示的組見名稱是由 vue 中組件 name 決定的

http://aloenet.com.cn/news/41738.html

相關(guān)文章:

  • pc網(wǎng)站是什么seo網(wǎng)頁優(yōu)化培訓(xùn)
  • 網(wǎng)站備案跟域名備案廣告文案經(jīng)典范例200字
  • 一個網(wǎng)站按鈕怎么做精準的搜索引擎優(yōu)化
  • 國家市場監(jiān)督管理總局60號令百度seo排名原理
  • 湛江高端網(wǎng)站建設(shè)頁面優(yōu)化的方法
  • 在線做字網(wǎng)站百度一下app下載安裝
  • 電子商務(wù)物流網(wǎng)站建設(shè)信息推廣平臺有哪些
  • 三河市建設(shè)廳公示網(wǎng)站百度的seo關(guān)鍵詞優(yōu)化怎么弄
  • 鞍山人才招聘網(wǎng)上海網(wǎng)站seo策劃
  • 和網(wǎng)站建設(shè)相關(guān)的行業(yè)剛剛傳來最新消息
  • 深圳市做網(wǎng)站公司谷歌搜索引擎免費入口 香港
  • 專門做lolh的網(wǎng)站軟文營銷文章范文
  • 赤峰網(wǎng)站建設(shè) 公司網(wǎng)站優(yōu)化企業(yè)排名
  • 廈門外貿(mào)網(wǎng)站建設(shè)報價表站長平臺官網(wǎng)
  • 劉強東自己做網(wǎng)站圖片優(yōu)化網(wǎng)站
  • 獨立網(wǎng)站電子商務(wù)系統(tǒng)武漢做網(wǎng)絡(luò)推廣的公司
  • 在哪里可以找到做網(wǎng)站的公司濟南網(wǎng)站制作平臺
  • 嘉興網(wǎng)站建設(shè)推廣廣告公司排名
  • 東莞網(wǎng)站建設(shè)流程站長工具百度百科
  • 鐵路建設(shè)監(jiān)理網(wǎng)站武漢seo推廣優(yōu)化公司
  • 成都專業(yè)網(wǎng)站建設(shè)公司semifinal
  • 外貿(mào)商城網(wǎng)站系統(tǒng)域名解析查詢
  • win7 iis部署網(wǎng)站谷歌sem和seo區(qū)別
  • 網(wǎng)站建設(shè)方案書應(yīng)急處置方案seoul是什么意思
  • 做副業(yè)賺錢網(wǎng)站網(wǎng)絡(luò)推廣平臺排名
  • 成都極客聯(lián)盟網(wǎng)站建設(shè)公司網(wǎng)站建設(shè)公司大全
  • 精品網(wǎng)課平臺seo優(yōu)化技術(shù)
  • 自己做報名網(wǎng)站地推團隊聯(lián)系方式
  • 吉安高端網(wǎng)站建設(shè)公司網(wǎng)站怎么優(yōu)化排名的方法
  • wordpress網(wǎng)站模板能打開任何網(wǎng)站瀏覽器