Vue相關(guān)面試題

對(duì)于MVVM的理解


MVVM是Model-View-ViewModel縮寫,也就是把MVC中的Controller演變成ViewModel。Model層代表數(shù)據(jù)模型,View代表UI組件,ViewModel是View和Model層的橋梁,數(shù)據(jù)會(huì)綁定到viewModel層并自動(dòng)將數(shù)據(jù)渲染到頁(yè)面中,視圖變化的時(shí)候會(huì)通知viewModel層更新數(shù)據(jù)。

MVVM 是 Model-View-ViewModel 的縮寫

Model: 代表數(shù)據(jù)模型,也可以在Model中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯。我們可以把Model稱為數(shù)據(jù)層,因?yàn)樗鼉H僅關(guān)注數(shù)據(jù)本身,不關(guān)心任何行為

View: 用戶操作界面。當(dāng)ViewModel對(duì)Model進(jìn)行更新的時(shí)候,會(huì)通過(guò)數(shù)據(jù)綁定更新到View

ViewModel:業(yè)務(wù)邏輯層,View需要什么數(shù)據(jù),ViewModel要提供這個(gè)數(shù)據(jù);View有某些操作,ViewModel就要響應(yīng)這些操作,所以可以說(shuō)它是Model for View.

MVVM模式簡(jiǎn)化了界面與業(yè)務(wù)的依賴,解決了數(shù)據(jù)頻繁更新。MVVM 在使用當(dāng)中,利用雙向綁定技術(shù),使得 Model 變化時(shí),ViewModel 會(huì)自動(dòng)更新,而 ViewModel 變化時(shí),View 也會(huì)自動(dòng)變化。


Vue生命周期

vue實(shí)例從創(chuàng)建到銷毀的過(guò)程,就是生命周期。從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom→渲染、更新→渲染、銷毀等一系列過(guò)程被稱之為vue生命周期。

vue生命周期掛在了很多鉤子函數(shù),我們可以更方便和更有邏輯的控制整個(gè)vue的實(shí)例化的過(guò)程

vue生命周期分為八個(gè)階段 創(chuàng)建前/后,加載前/后 ,更新前/后,銷毀前/后?

頁(yè)面第一次加載的時(shí)候 會(huì)觸發(fā)beforeCreate、created、beforeMount、mounted這幾個(gè)鉤子,在mounted的時(shí)候會(huì)渲染完成DOM。


Vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定的原理:Object.defineProperty()

vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過(guò)?Object.defineProperty()?來(lái)劫持各個(gè)屬性的setter,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)監(jiān)聽回調(diào)。當(dāng)把一個(gè)普通?Javascript?對(duì)象傳給 Vue 實(shí)例來(lái)作為它的?data?選項(xiàng)時(shí),Vue 將遍歷它的屬性,用?Object.defineProperty()?將它們轉(zhuǎn)為?getter/setter。用戶看不到?getter/setter,但是在內(nèi)部它們讓?Vue追蹤依賴,在屬性被訪問(wèn)和修改時(shí)通知變化。

vue的數(shù)據(jù)雙向綁定 將MVVM作為數(shù)據(jù)綁定的入口,整合Observer,Compile和Watcher三者,通過(guò)Observer來(lái)監(jiān)聽自己的model的數(shù)據(jù)變化,通過(guò)Compile來(lái)解析編譯模板指令(vue中是用來(lái)解析?{{}}),最終利用watcher搭起observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 —>視圖更新;視圖交互變化(input)—>數(shù)據(jù)model變更雙向綁定效果。


vue實(shí)現(xiàn)雙向綁定原理

Vue組件之間傳遞參數(shù)

父子之間傳遞參數(shù):父組件傳給子組件:子組件通過(guò)props方法接受數(shù)據(jù);子組件傳給父組件:$emit?方法傳遞參數(shù)

非父子組件間的數(shù)據(jù)傳遞,兄弟組件傳值? 用eventBus(適合小項(xiàng)目)或者VUEX


Vue路由

路由模式:hash模式 和 history模式

hash模式:在瀏覽器中符號(hào)“#”,#以及#后面的字符稱之為hash,用?window.location.hash?讀取。特點(diǎn):hash雖然在URL中,但不被包括在HTTP請(qǐng)求中;用來(lái)指導(dǎo)瀏覽器動(dòng)作,對(duì)服務(wù)端安全無(wú)用,hash不會(huì)重加載頁(yè)面。

history模式:history采用HTML5的新特性;且提供了兩個(gè)新方法:pushState(),?replaceState()可以對(duì)瀏覽器歷史記錄棧進(jìn)行修改,以及popState事件的監(jiān)聽到狀態(tài)變更


路由鉤子函數(shù)

全局鉤子函數(shù)(beforeEach、afterEach)

路由獨(dú)享的鉤子函數(shù)(beforeEnter)

組件內(nèi)鉤子函數(shù)(beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave)

beforeEach一共接收三個(gè)參數(shù),分別是to、from、next;to:即將進(jìn)入的路由對(duì)象;from:正要離開的路由對(duì)象;next:路由的控制參數(shù);

AfterEach和beforeEach一樣都是屬于全局守衛(wèi)鉤子,都是在main.js中進(jìn)行調(diào)用;其中AfterEach比beforeEach少一個(gè)next參數(shù);to:即將要進(jìn)入的路由對(duì)象;from:正要離開的路由對(duì)象;

beforeEneter?指定的路由才有的鉤子函數(shù),通常這類路由獨(dú)享的鉤子函數(shù)我們是在路由配置文件中進(jìn)行配置,只能設(shè)置改變前的鉤子,不能設(shè)置改變后的鉤子,只能在設(shè)置的路由 才能觸發(fā)這個(gè)鉤子函數(shù),其他頁(yè)面是不會(huì)觸發(fā)的,也有to,from,next三個(gè)參數(shù)

beforeRouterEnter(to,from,next)是唯一一個(gè)不能使用this的鉤子函數(shù),因?yàn)榇藭r(shí)的vue實(shí)例還沒(méi)有創(chuàng)建;to:即將要進(jìn)入的路由對(duì)象;from:正要離開的路由對(duì)象;next:路由控制參數(shù)

beforeRouterUpdate(to,from,next)?在路由發(fā)生修改的時(shí)候進(jìn)行調(diào)用

beforeRouterLeave(to,from,next)?在路由離開該組件時(shí)調(diào)用;

路由之間跳轉(zhuǎn)

<router-link?:to="index"> 或者?router.push('index')

$route和$router的區(qū)別

$route是“路由信息對(duì)象”,包括path,params,hash,query,fullPath,matched,name等路由信息參數(shù);而$router是“路由實(shí)例”對(duì)象包括了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等

例如? ?? this.$router.push({

? ? ? ? ? ? ? ?path: "/ems/emsAddPlan",

? ? ? ? ? ? ? ?query: { id: this.$route.query.id }

? ? ? ? ?});


?v-if 和 v-show 區(qū)別

v-if按照條件是否渲染,v-show是display的block或none;


如何讓CSS只在當(dāng)前組件中起作用?

將當(dāng)前組件的<style>修改為<style scoped>

scoped樣式穿透:使用/deep/或者另外寫一個(gè)style樣式 不加scoped


<keep-alive></keep-alive>的作用是什么?

keep-alive可以實(shí)現(xiàn)組件緩存,當(dāng)組件切換時(shí)不會(huì)對(duì)當(dāng)前組件進(jìn)行卸載

<keep-alive></keep-alive>?包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,主要用于保留組件狀態(tài)或避免重新渲染

比如有一個(gè)列表和一個(gè)詳情,那么用戶就會(huì)經(jīng)常執(zhí)行打開詳情=>返回列表=>打開詳情…這樣的話列表和詳情都是一個(gè)頻率很高的頁(yè)面,那么就可以對(duì)列表組件使用<keep-alive></keep-alive>進(jìn)行緩存,這樣用戶每次返回列表的時(shí)候,都能從緩存中快速渲染,而不是重新渲染

常用的兩個(gè)屬性include/exclude,允許組件有條件的進(jìn)行緩存

兩個(gè)生命周期activated/deactivated,用來(lái)得知當(dāng)前組件是否處于活躍狀態(tài)


指令v-el的作用是什么?

提供一個(gè)在頁(yè)面上已存在的?DOM元素作為?Vue實(shí)例的掛載目標(biāo).可以是 CSS 選擇器,也可以是一個(gè)?HTMLElement?實(shí)例


在Vue中使用插件的步驟

采用ES6的import ... from ...語(yǔ)法或CommonJS的require()方法引入插件

使用全局方法Vue.use( plugin )使用插件,可以傳入一個(gè)選項(xiàng)對(duì)象Vue.use(MyPlugin, { someOption: true })


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

每個(gè)組件都是?Vue?的實(shí)例。

組件共享?data?屬性,當(dāng)?data?的值是同一個(gè)引用類型的值時(shí),改變其中一個(gè)會(huì)影響其他


Vue computed 實(shí)現(xiàn)

初始化?data, 使用?Object.defineProperty?把這些屬性全部轉(zhuǎn)為?getter/setter。

初始化?computed, 遍歷?computed?里的每個(gè)屬性,每個(gè)?computed?屬性都是一個(gè)?watch?實(shí)例。每個(gè)屬性提供的函數(shù)作為屬性的?getter,使用?Object.defineProperty?轉(zhuǎn)化。

Object.defineProperty getter?依賴收集。用于依賴發(fā)生變化時(shí),觸發(fā)屬性重新計(jì)算。

若出現(xiàn)當(dāng)前?computed?計(jì)算屬性嵌套其他?computed?計(jì)算屬性時(shí),先進(jìn)行其他的依賴收集

computed和watch區(qū)別

當(dāng)頁(yè)面中有某些數(shù)據(jù)依賴其他數(shù)據(jù)進(jìn)行變動(dòng)的時(shí)候,可以使用計(jì)算屬性computed

watch用于觀察和監(jiān)聽頁(yè)面上的vue實(shí)例,如果要在數(shù)據(jù)變化的同時(shí)進(jìn)行異步操作或者是比較大的開銷,那么watch為最佳選擇


vue修飾符

stop:阻止事件的冒泡

prevent:阻止事件的默認(rèn)行為

once:只觸發(fā)一次

self:只觸發(fā)自己的事件行為時(shí),才會(huì)執(zhí)行

vue.extend和vue.component

extend是構(gòu)造一個(gè)組件的語(yǔ)法器。然后這個(gè)組件你可以作用到Vue.component這個(gè)全局注冊(cè)方法里還可以在任意vue模板里使用組件。也可以作用到vue實(shí)例或者某個(gè)組件中的components屬性中并在內(nèi)部使用apple組件。

Vue.component你可以創(chuàng)建 ,也可以取組件。


vue的優(yōu)點(diǎn)是什么

低耦合。視圖(View)可以獨(dú)立于Model變化和修改,一個(gè)ViewModel可以綁定到不同的"View"上,當(dāng)View變化的時(shí)候Model可以不變,當(dāng)Model變化的時(shí)候View也可以不變

可重用性。你可以把一些視圖邏輯放在一個(gè)ViewModel里面,讓很多view重用這段視圖邏輯

可測(cè)試。界面素來(lái)是比較難于測(cè)試的,而現(xiàn)在測(cè)試可以針對(duì)ViewModel來(lái)寫


vue項(xiàng)目中的性能優(yōu)化

代碼層面:

1 不要在模板里面寫過(guò)多表達(dá)式

2 循環(huán)調(diào)用子組件時(shí)添加key,并且避免使用v-for的時(shí)候同時(shí)使用v-if

3 頻繁切換的使用v-show,不頻繁切換的使用v-if

4 盡量少用float,可以用flex

5 按需加載,可以用require或者import()按需加載需要的組件

6 路由懶加載,圖片懶加載,第三方插件按需引入

7 區(qū)分?computed?和?watch?的使用

8 通過(guò)?addEventListener添加的事件在組件銷毀時(shí)要用?removeEventListener?手動(dòng)移除這些事件的監(jiān)聽

9 SSR服務(wù)端渲染,首屏加載速度快,SEO效果好

Webpack 層面優(yōu)化:

1 對(duì)圖片進(jìn)行壓縮

2 使用?CommonsChunkPlugin?插件提取公共代碼

3 提取組件的 CSS

4 優(yōu)化?SourceMap

5 構(gòu)建結(jié)果輸出分析,利用?webpack-bundle-analyzer?可視化分析工具


Vue的SPA 如何優(yōu)化加載速度

減少入口文件體積

靜態(tài)資源本地緩存

開啟Gzip壓縮

使用SSR,nuxt.js


Vue與Angular以及React的區(qū)別?

Vue與AngularJS的區(qū)別

Angular采用TypeScript開發(fā), 而Vue可以使用javascript也可以使用TypeScript

AngularJS依賴對(duì)數(shù)據(jù)做臟檢查,所以Watcher越多越慢;Vue.js使用基于依賴追蹤的觀察并且使用異步隊(duì)列更新,所有的數(shù)據(jù)都是獨(dú)立觸發(fā)的。

AngularJS社區(qū)完善, Vue的學(xué)習(xí)成本較小

Vue與React的區(qū)別

vue組件分為全局注冊(cè)和局部注冊(cè),在react中都是通過(guò)import相應(yīng)組件,然后模版中引用;

props是可以動(dòng)態(tài)變化的,子組件也實(shí)時(shí)更新,在react中官方建議props要像純函數(shù)那樣,輸入輸出一致對(duì)應(yīng),而且不太建議通過(guò)props來(lái)更改視圖;

子組件一般要顯示地調(diào)用props選項(xiàng)來(lái)聲明它期待獲得的數(shù)據(jù)。而在react中不必需,另兩者都有props校驗(yàn)機(jī)制;

每個(gè)Vue實(shí)例都實(shí)現(xiàn)了事件接口,方便父子組件通信,小型項(xiàng)目中不需要引入狀態(tài)管理機(jī)制,而react必需自己實(shí)現(xiàn);

使用插槽分發(fā)內(nèi)容,使得可以混合父組件的內(nèi)容與子組件自己的模板;

多了指令系統(tǒng),讓模版可以實(shí)現(xiàn)更豐富的功能,而React只能使用JSX語(yǔ)法;

Vue增加的語(yǔ)法糖computed和watch,而在React中需要自己寫一套邏輯來(lái)實(shí)現(xiàn);

react的思路是all in js,通過(guò)js來(lái)生成html,所以設(shè)計(jì)了jsx,還有通過(guò)js來(lái)操作css,社區(qū)的styled-component、jss等;而 vue是把html,css,js組合到一起,用各自的處理方式,vue有單文件組件,可以把html、css、js寫到一個(gè)文件中,html提供了模板引擎來(lái)處理。

react做的事情很少,很多都交給社區(qū)去做,vue很多東西都是內(nèi)置的,寫起來(lái)確實(shí)方便一些, 比如 redux的combineReducer就對(duì)應(yīng)vuex的modules, 比如reselect就對(duì)應(yīng)vuex的getter和vue組件的computed, vuex的mutation是直接改變的原始數(shù)據(jù),而redux的reducer是返回一個(gè)全新的state,所以redux結(jié)合immutable來(lái)優(yōu)化性能,vue不需要。

react是整體的思路的就是函數(shù)式,所以推崇純組件,數(shù)據(jù)不可變,單向數(shù)據(jù)流,當(dāng)然需要雙向的地方也可以做到,比如結(jié)合redux-form,組件的橫向拆分一般是通過(guò)高階組件。而vue是數(shù)據(jù)可變的,雙向綁定,聲明式的寫法,vue組件的橫向拆分很多情況下用mixin


vuex是什么?怎么使用?哪種功能場(chǎng)景使用它?

vuex 就是一個(gè)倉(cāng)庫(kù),倉(cāng)庫(kù)里放了很多對(duì)象。其中 state 就是數(shù)據(jù)源存放地,對(duì)應(yīng)于一般 vue 對(duì)象里面的 data

state 里面存放的數(shù)據(jù)是響應(yīng)式的,vue 組件從 store 讀取數(shù)據(jù),若是 store 中的數(shù)據(jù)發(fā)生改變,依賴這相數(shù)據(jù)的組件也會(huì)發(fā)生更新

它通過(guò) mapState 把全局的 state 和 getters 映射到當(dāng)前組件的 computed 計(jì)算屬性。

Vuex有5種屬性: 分別是 state、getter、mutation、action、module;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容