本篇文章給大家分享一些Vue面試題(附答案解析)。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有所幫助。
文章所涉及的資料來自互聯(lián)網(wǎng)整理和個人總結(jié),意在于個人學習和經(jīng)驗匯總,如有什么地方侵權(quán),請聯(lián)系本人刪除,謝謝!
1、對于MVVM的理解
MVVM 是 Model-View-ViewModel 的縮寫。
Model代表數(shù)據(jù)模型,也可以在Model中定義數(shù)據(jù)修改和操作的業(yè)務邏輯。
View 代表UI 組件,它負責將數(shù)據(jù)模型轉(zhuǎn)化成UI 展現(xiàn)出來。
ViewModel 監(jiān)聽模型數(shù)據(jù)的改變和控制視圖行為、處理用戶交互,簡單理解就是一個同步View 和 Model的對象,連接Model和View。
在MVVM架構(gòu)下,View 和 Model 之間并沒有直接的聯(lián)系,而是通過ViewModel進行交互,Model 和 ViewModel 之間的交互是雙向的, 因此View 數(shù)據(jù)的變化會同步到Model中,而Model 數(shù)據(jù)的變化也會立即反應到View 上。
ViewModel 通過雙向數(shù)據(jù)綁定把 View 層和 Model 層連接了起來,而View 和 Model 之間的同步工作完全是自動的,無需人為干涉,因此開發(fā)者只需關(guān)注業(yè)務邏輯,不需要手動操作DOM, 不需要關(guān)注數(shù)據(jù)狀態(tài)的同步問題,復雜的數(shù)據(jù)狀態(tài)維護完全由 MVVM 來統(tǒng)一管理。
2、vue實現(xiàn)雙向數(shù)據(jù)綁定
vue實現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在數(shù)據(jù)變動時發(fā)布消息給訂閱者,觸發(fā)相應監(jiān)聽回調(diào)。當把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉(zhuǎn)為 getter/setter。用戶看不到 getter/setter,但是在內(nèi)部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。(學習視頻分享:vue視頻教程)
vue的數(shù)據(jù)雙向綁定 將MVVM作為數(shù)據(jù)綁定的入口,整合Observer,Compile和Watcher三者,通過Observer來監(jiān)聽自己的model的數(shù)據(jù)變化,通過Compile來解析編譯模板指令(vue中是用來解析 {{}}),最終利用watcher搭起observer和Compile之間的通信橋梁,達到數(shù)據(jù)變化 —>視圖更新;視圖交互變化(input)—>數(shù)據(jù)model變更雙向綁定效果。
3、Vue組件間的參數(shù)傳遞
1.父組件與子組件傳值
父組件傳給子組件:子組件通過props方法接受數(shù)據(jù); 子組件傳給父組件:$emit方法傳遞參數(shù)
2.非父子組件間的數(shù)據(jù)傳遞,兄弟組件傳值
eventBus,就是創(chuàng)建一個事件中心,相當于中轉(zhuǎn)站,可以用它來傳遞事件和接收事件。項目比較小時,用這個比較合適。
4、v-show 與 v-if 區(qū)別
-
v-show和v-if的區(qū)別:
v-show是css切換,v-if是完整的銷毀和重新創(chuàng)建。
-
使用
頻繁切換時用v-show,運行時較少改變時用v-if
v-if=‘false’ v-if是條件渲染,當false的時候不會渲染
5、Vue的生命周期
beforeCreate(創(chuàng)建前) 在數(shù)據(jù)觀測和初始化事件還未開始
created(創(chuàng)建后) 完成數(shù)據(jù)觀測,屬性和方法的運算,初始化事件,$el屬性還沒有顯示出來
beforeMount(載入前) 在掛載開始之前被調(diào)用,相關(guān)的render函數(shù)首次被調(diào)用。實例已完成以下的配置:編譯模板,把data里面的數(shù)據(jù)和模板生成html。注意此時還沒有掛載html到頁面上。
mounted(載入后) 在el 被新創(chuàng)建的 vm.$el 替換,并掛載到實例上去之后調(diào)用。實例已完成以下的配置:用上面編譯好的html內(nèi)容替換el屬性指向的DOM對象。完成模板中的html渲染到html頁面中。此過程中進行ajax交互。
beforeUpdate(更新前) 在數(shù)據(jù)更新之前調(diào)用,發(fā)生在虛擬DOM重新渲染和打補丁之前。可以在該鉤子中進一步地更改狀態(tài),不會觸發(fā)附加的重渲染過程。
updated(更新后) 在由于數(shù)據(jù)更改導致的虛擬DOM重新渲染和打補丁之后調(diào)用。調(diào)用時,組件DOM已經(jīng)更新,所以可以執(zhí)行依賴于DOM的操作。然而在大多數(shù)情況下,應該避免在此期間更改狀態(tài),因為這可能會導致更新無限循環(huán)。該鉤子在服務器端渲染期間不被調(diào)用。
beforeDestroy(銷毀前) 在實例銷毀之前調(diào)用。實例仍然完全可用。
destroyed(銷毀后) 在實例銷毀之后調(diào)用。調(diào)用后,所有的事件監(jiān)聽器會被移除,所有的子實例也會被銷毀。該鉤子在服務器端渲染期間不被調(diào)用。
1.什么是vue生命周期?
答: Vue 實例從創(chuàng)建到銷毀的過程,就是生命周期。從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom→渲染、更新→渲染、銷毀等一系列過程,稱之為 Vue 的生命周期。
2.vue生命周期的作用是什么?
答:它的生命周期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯。
3.vue生命周期總共有幾個階段?
答:它可以總共分為8個階段:創(chuàng)建前/后, 載入前/后,更新前/后,銷毀前/銷毀后。
4.第一次頁面加載會觸發(fā)哪幾個鉤子?
答:會觸發(fā) 下面這幾個beforeCreate, created, beforeMount, mounted 。
5.DOM 渲染在 哪個周期中就已經(jīng)完成?
答:DOM 渲染在 mounted 中就已經(jīng)完成了。
5、綁定 class 的數(shù)組用法
- 對象方法
v-bind:class="{'orange': isRipe, 'green': isNotRipe}"
- 數(shù)組方法
v-bind:class="[class1, class2]"
- 行內(nèi)
v-bind:style="{color: color, fontSize: fontSize+'px' }"
6、計算屬性computed和 監(jiān)聽watch 的區(qū)別
計算屬性是自動監(jiān)聽依賴值的變化,從而動態(tài)返回內(nèi)容,監(jiān)聽是一個過程,在監(jiān)聽的值變化時,可以觸發(fā)一個回調(diào),并做一些事情。 所以區(qū)別來源于用法,只是需要動態(tài)值,那就用計算屬性;需要知道值的改變后執(zhí)行業(yè)務邏輯,才用 watch,用反或混用雖然可行,但都是不正確的用法。
1、computed 是一個對象時,它有哪些選項?
有g(shù)et和set兩個選項
2、computed 和 methods 有什么區(qū)別?
methods是一個方法,它可以接受參數(shù),而computed不能,computed是可以緩存的,methods不會
3、computed 是否能依賴其它組件的數(shù)據(jù)?
computed可以依賴其他computed,甚至是其他組件的data
4、watch 是一個對象時,它有哪些選項?
handler deep 是否深度 immeditate 是否立即執(zhí)行
總結(jié)
當有一些數(shù)據(jù)需要隨著另外一些數(shù)據(jù)變化時,建議使用computed。 當有一個通用的響應數(shù)據(jù)變化的時候,要執(zhí)行一些業(yè)務邏輯或異步操作的時候建議使用watcher
7、Vue的路由實現(xiàn):hash模式 和 history模式
hash模式:在瀏覽器中符號“#”,#以及#后面的字符稱之為hash,用window.location.hash讀取; 特點:hash雖然在URL中,但不被包括在HTTP請求中;用來指導瀏覽器動作,對服務端安全無用,hash不會重加載頁面。 hash 模式下,僅 hash 符號之前的內(nèi)容會被包含在請求中,如 http://www.xxx.com,因此對于后端來說,即使沒有做到對路由的全覆蓋,也不會返回 404 錯誤。
history模式:history采用HTML5的新特性;且提供了兩個新方法:pushState(),replaceState()可以對瀏覽器歷史記錄棧進行修改,以及popState事件的監(jiān)聽到狀態(tài)變更。 history 模式下,前端的 URL 必須和實際向后端發(fā)起請求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少對 /items/id 的路由處理,將返回 404 錯誤。
8、Vue與Angular以及React的區(qū)別?
(版本在不斷更新,以下的區(qū)別有可能不是很正確。我工作中只用到vue,對angular和react不怎么熟)
1.與AngularJS的區(qū)別
相同點:
都支持指令:內(nèi)置指令和自定義指令;都支持過濾器:內(nèi)置過濾器和自定義過濾器;都支持雙向數(shù)據(jù)綁定;都不支持低端瀏覽器。
不同點:
AngularJS的學習成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比較簡單、直觀;在性能上,AngularJS依賴對數(shù)據(jù)做臟檢查,所以Watcher越多越慢;Vue.js使用基于依賴追蹤的觀察并且使用異步隊列更新,所有的數(shù)據(jù)都是獨立觸發(fā)的。
2.與React的區(qū)別
相同點:
React采用特殊的JSX語法,Vue.js在組件開發(fā)中也推崇編寫.vue特殊文件格式,對文件內(nèi)容都有一些約定,兩者都需要編譯后使用;中心思想相同:一切都是組件,組件實例之間可以嵌套;都提供合理的鉤子函數(shù),可以讓開發(fā)者定制化地去處理需求;都不內(nèi)置列數(shù)AJAX,Route等功能到核心包,而是以插件的方式加載;在組件開發(fā)中都支持mixins的特性。
不同點:
React采用的Virtual DOM會對渲染出來的結(jié)果做臟檢查;Vue.js在模板中提供了指令,過濾器等,可以非常方便,快捷地操作Virtual DOM。
9、事件修飾符
綁定一個原生的click事件: 加native,
其他事件修飾符:stop prevent self
組合鍵:click.ctrl.exact 只有ctrl被按下的時候才觸發(fā)
10、組件中 data 為什么是函數(shù)
為什么組件中的 data 必須是一個函數(shù),然后 return 一個對象,而 new Vue 實例里,data 可以直接是一個對象?
因為組件是用來復用的,JS 里對象是引用關(guān)系,這樣作用域沒有隔離,而 new Vue 的實例,是不會被復用的,因此不存在引用對象的問題
對于Vue是一套漸進式框架的理解
11、漸進式代表的含義是:主張最少。
Vue可能有些方面是不如React,不如Angular,但它是漸進的,沒有強主張,你可以在原有大系統(tǒng)的上面,把一兩個組件改用它實現(xiàn),當jQuery用;也可以整個用它全家桶開發(fā),當Angular用;還可以用它的視圖,搭配你自己設計的整個下層用。你可以在底層數(shù)據(jù)邏輯的地方用OO和設計模式的那套理念,也可以函數(shù)式,都可以,它只是個輕量視圖而已,只做了自己該做的事,沒有做不該做的事,僅此而已。 漸進式的含義,我的理解是:沒有多做職責之外的事。
12、vue.js的兩個核心是什么?
數(shù)據(jù)驅(qū)動和組件化
13、vue中 key
值的作用
使用key來給每個節(jié)點做一個唯一標識
key的作用主要是為了高效的更新虛擬DOM。另外vue中在使用相同標簽名元素的過渡切換時,也會使用到key屬性,其目的也是為了讓vue可以區(qū)分它們,否則vue只會替換其內(nèi)部屬性而不會觸發(fā)過渡效果。
14、v-for 與 v-if 的優(yōu)先級
v-for的優(yōu)先級比v-if高
15、組件
1、vue中子組件調(diào)用父組件的方法
第一種方法是直接在子組件中通過this.$parent.event來調(diào)用父組件的方法。
第二種方法是在子組件里用$emit
向父組件觸發(fā)一個事件,父組件監(jiān)聽這個事件就行了。
第三種是父組件把方法傳入子組件中,在子組件里直接調(diào)用這個方法。
2、vue中父組件調(diào)用子組件的方法
父組件利用ref屬性操作子組件方法。
父:
<child ref="childMethod"></child>
子:
method: {
test() {
alert(1)
}
}
在父組件里調(diào)用test即 this.$refs.childMethod.test()
3、vue組件之間傳值
(1)父組件給子組件傳值:
- 父組件調(diào)用子組件的時候動態(tài)綁定屬性
<parent :dataList='dataList'></parent>
子組件定義props接收動態(tài)綁定的屬性props: ['dataList']
子組件使用數(shù)據(jù)
(2)子組件主動獲取父子間的屬性和方法:
在子組件中使用this.parent.方法。
(3)子組件給父組件傳值:
一、使用ref屬性
1.父組件調(diào)用子組件時綁定屬性ref
<parent :ref='parent'></parent>
2.在父組件中使用this.refs.parent.方法
二、使用emit('方法名‘,傳值)
2.父組件通過子組件綁定的'方法名'獲取傳值。
(4)vue頁面級組件之間傳值
使用vue-router通過跳轉(zhuǎn)鏈接帶參數(shù)傳參。
使用本地緩存localStorge。
使用vuex數(shù)據(jù)管理傳值。
(5)說說vue的動態(tài)組件。
多個組件通過同一個掛載點進行組件的切換,is的值是哪個組件的名稱,那么頁面就會顯示哪個組件。
(6)keep-alive內(nèi)置組件的作用
可以讓當前組件或者路由不經(jīng)歷創(chuàng)建和銷毀,而是進行緩存,凡是被keep-alive組件包裹的組件,除了第一次以外。不會經(jīng)歷創(chuàng)建和銷毀階段的。第一次創(chuàng)建后就會緩存到緩存當
(7)遞歸組件的用法
組件是可以在它們自己的模板中調(diào)用自身的。不過它們只能通過 name 選項來做這件事。首先我們要知道,既然是遞歸組件,那么一定要有一個結(jié)束的條件,否則就會使用組件循環(huán)引用,最終出現(xiàn)“max stack size exceeded”的錯誤,也就是棧溢出。那么,我們可以使用v-if="false"作為遞歸組件的結(jié)束條件。當遇到v-if為false時,組件將不會再進行渲染。
16、怎么定義vue-router的動態(tài)路由?怎么獲取傳過來的值?
動態(tài)路由的創(chuàng)建,主要是使用path屬性過程中,使用動態(tài)路徑參數(shù),以冒號開頭,如下:
{
path: '/details/:id'
name: 'Details'
components: Details
}
訪問details目錄下的所有文件,如果details/a,details/b等,都會映射到Details組件上。
當匹配到/details下的路由時,參數(shù)值會被設置到this.$route.params下,所以通過這個屬性可以獲取動態(tài)參數(shù)
this.$route.params.id
17、vue-router有哪幾種路由守衛(wèi)?
全局守衛(wèi):beforeEach
后置守衛(wèi):afterEach
全局解析守衛(wèi):beforeResolve
路由獨享守衛(wèi):beforeEnter
18、
router的區(qū)別是什么?
$router為VueRouter的實例,是一個全局路由對象,包含了路由跳轉(zhuǎn)的方法、鉤子函數(shù)等。
$route 是路由信息對象||跳轉(zhuǎn)的路由對象,每一個路由都會有一個route對象,是一個局部對象,包含path,params,hash,query,fullPath,matched,name等路由信息參數(shù)。
19、vue-router響應路由參數(shù)的變化
(1)用watch 檢測
(2)組件內(nèi)導航鉤子函數(shù)
20、 vue-router 傳參
(1)使用Params:
只能使用name,不能使用path
參數(shù)不會顯示在路徑上
瀏覽器強制刷新參數(shù)會被清空
(2)使用Query:
參數(shù)會顯示在路徑上,刷新不會被清空
name 可以使用path路徑
21、不用Vuex會帶來什么問題?
1、可維護性會下降,你要想修改數(shù)據(jù),你得維護三個地方
2、可讀性會下降,因為一個組件里的數(shù)據(jù),你根本就看不出來是從哪來的
3、增加耦合,大量的上傳派發(fā),會讓耦合性大大的增加,本來Vue用Component就是為了減少耦合,現(xiàn)在這么用,和組件化的初衷相背。
22、vuex有哪幾種屬性?
有五種,分別是 State、 Getter、Mutation 、Action、 Module。
23、、vuex的State特性是?
1、Vuex就是一個倉庫,倉庫里面放了很多對象。其中state就是數(shù)據(jù)源存放地,對應于與一般Vue對象里面的data
2、state里面存放的數(shù)據(jù)是響應式的,Vue組件從store中讀取數(shù)據(jù),若是store中的數(shù)據(jù)發(fā)生改變,依賴這個數(shù)據(jù)的組件也會發(fā)生更新
3、它通過mapState把全局的 state 和 getters 映射到當前組件的 computed 計算屬性中
24、vuex的Getter特性是?
1、getters 可以對State進行計算操作,它就是Store的計算屬性
2、 雖然在組件內(nèi)也可以做計算屬性,但是getters 可以在多組件之間復用
3、 如果一個狀態(tài)只在一個組件內(nèi)使用,是可以不用getters
25、vuex的Mutation特性是?
1、Action 類似于 mutation,不同在于:
2、Action 提交的是 mutation,而不是直接變更狀態(tài)。
3、Action 可以包含任意異步操作
26、Vue.js中ajax請求代碼應該寫在組件的methods中還是vuex的actions中?
1、如果請求來的數(shù)據(jù)是不是要被其他組件公用,僅僅在請求的組件內(nèi)使用,就不需要放入vuex 的state里。
2、如果被其他地方復用,這個很大幾率上是需要的,如果需要,請將請求放入action里,方便復用,并包裝成promise返回,在調(diào)用處用async await處理返回的數(shù)據(jù)。如果不要復用這個請求,那么直接寫在vue文件里很方便。
27、vue雙向數(shù)據(jù)綁定原理、vue2和vue3原理的不同點
因為vue2.0 object.defineProperty只能劫持對象屬性,無法監(jiān)控數(shù)組下標的變化,導致通過數(shù)據(jù)下標添加的元素不能實時響應的弊端。為了解決這個問題,經(jīng)vue內(nèi)部處理后,可以使用push()、pop() 、shift()、unshift()、splice()、sort()、reverse()進行hack處理,所以其他數(shù)組屬性也是監(jiān)測不到,具有一定的局限性。
因為object.defineProperty只能劫持對象屬性,從而需要對每個對象的每個屬性進行遍歷。vue2.0里是通過遞歸+遍歷data對象來實現(xiàn)對數(shù)據(jù)的監(jiān)控的,如果屬性值是對象的話,還需要深度遍歷。
而Vue3.0中的proxy不僅可以代理對象,還可以代理數(shù)組,也可以代理動態(tài)添加的屬性,有13種劫持操作: get 獲取某個key值 (接收2個參數(shù),目標值和目標值key值) set 設置某個key值 (目標值、目標的key值、要改變的值、改變前的原始值) apply 使用in 操作符判斷某個key是否存在 deleteProperty 刪除一個property defineProperty 定義一個新的property
感謝
更多編程相關(guān)知識,請訪問:編程視頻!!