這篇文章跟大家分享一些Vue面試題(附答案解析)。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
文章所涉及的資料來自網路整理和個人總結,意在於個人學習和經驗匯總,如有什麼地方侵權,請聯繫本人刪除,謝謝!
MVVM 是 Model-View-ViewModel 的縮寫。
Model代表資料模型,也可以在Model中定義資料修改和操作的業務邏輯。
View 代表UI 元件,它負責將資料模型轉換成UI 展現出來。
ViewModel 監聽模型資料的改變和控制視圖行為、處理使用者交互,簡單理解就是一個同步View 和 Model的對象,連接Model和View。
在MVVM架構下,View 與Model 之間並沒有直接的聯繫,而是透過ViewModel進行交互,Model 與ViewModel 之間的交互是雙向的, 因此View 資料的變化會同步到Model中,而Model 資料的變化也會立即反應到View 上。
ViewModel 透過雙向資料綁定把View 層和Model 層連接了起來,而View 和Model 之間的同步工作完全是自動的,無需人為干涉,因此開發者只需專注於業務邏輯,不需要手動操作DOM, 不需要關注資料狀態的同步問題,複雜的資料狀態維護完全由MVVM 來統一管理。
vue實作資料雙向綁定主要是:採用資料劫持結合發布者-訂閱者模式的方式,透過Object.defineProperty()來劫持各個屬性的setter,getter,在資料變動時發布訊息給訂閱者,觸發對應監聽回呼。當把一個普通 Javascript 物件傳給 Vue 實例來當作它的 data 選項時,Vue 會遍歷它的屬性,用 Object.defineProperty 將它們轉為 getter/setter。使用者看不到 getter/setter,但是在內部它們讓 Vue 追蹤依賴,在屬性被存取和修改時通知變化。 (學習影片分享:vue影片教學)
vue的資料雙向綁定將MVVM作為資料綁定的入口,整合Observer,Compile和Watcher三者,透過Observer來監聽自己的model的資料變化,透過Compile來解析編譯模板指令(vue中是用來解析{{}}),最後利用watcher搭起observer和Compile之間的通訊橋樑,達到資料變化—>視圖更新;視圖互動變化(input)—>資料model變更雙向綁定效果。
父元件傳給子元件:子元件透過props方法接受資料; 子元件傳給父元件:$emit方法傳遞參數
eventBus,就是建立一個事件中心,相當於中繼站,可以用它來傳遞事件和接收事件。項目比較小時,用這個比較適合。
# v-show是css切換,v-if是完整的銷毀和重新創建。
頻繁切換時用v-show,執行時間較少改變時用v-if
v -if='false' v-if是條件渲染,當false的時候不會渲染
##### ###beforeCreate###(建立前) 在資料觀測與初始化事件尚未開始 #########created###(建立後) 完成資料觀測,屬性與方法的運算,初始化事件, $el屬性還沒有顯示出來 #########beforeMount###(載入前) 在掛載開始之前被調用,相關的render函數首次被調用。實例已完成以下的設定:編譯模板,把data裡面的資料和模板產生html。注意此時還沒有掛載html到頁面上。 #########mounted###(載入後) 在el 被新建立的 vm.$el 替換,並掛載到實例上去之後呼叫。實例已完成以下的配置:用上面編譯好的html內容取代el屬性指向的DOM物件。完成模板中的html渲染到html頁面。此過程中進行ajax互動。 #########beforeUpdate###(更新前) 在資料更新之前調用,發生在虛擬DOM重新渲染和打補丁之前。可以在該鉤子中進一步更改狀態,不會觸發附加的重渲染過程。 ###
updated(更新後) 在資料變更導致的虛擬DOM重新渲染和打補丁之後呼叫。呼叫時,元件DOM已經更新,所以可以執行依賴DOM的操作。然而在大多數情況下,應避免在此期間更改狀態,因為這可能會導致更新無限循環。該鉤子在伺服器端渲染期間不被調用。
beforeDestroy(銷毀前) 在實例銷毀之前呼叫。實例仍然完全可用。
destroyed(銷毀後) 在實例銷毀之後呼叫。呼叫後,所有的事件監聽器會被移除,所有的子實例也會被銷毀。該鉤子在伺服器端渲染期間不被調用。
答案: Vue 實例從創建到銷毀的過程,就是生命週期。從開始建立、初始化資料、編譯模板、掛載Dom→渲染、更新→渲染、銷毀等一系列過程,稱為 Vue 的生命週期。
答案:它的生命週期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯。
答案:它可以總共分為8個階段:建立前/後, 載入前/後,更新前/後,銷毀前/銷毀後。
答:會觸發 下面這幾個beforeCreate, created, beforeMount, mounted 。
答:DOM 渲染在 mounted 中就已經完成了。
v-bind:class="{'orange': isRipe, 'green ': isNotRipe}"
v-bind:class="[class1, class2]"
v-bind:style ="{color: color, fontSize: fontSize 'px' }"
#計算屬性是自動監聽依賴值的變化,從而動態傳回內容,監聽是一個過程,當監聽的值變化時,可以觸發一個回調,並做一些事情。所以差異來自用法,只是需要動態值,那就用計算屬性;需要知道值的改變後執行業務邏輯,才用 watch,用反或混用雖然可行,但都是不正確的用法。
有get和set兩個選項
methods是一個方法,它可以接受參數,而computed不能,computed是可以快取的,methods不會
computed可以依賴其他computed,甚至是其他元件的data
handler deep 是否深度 immeditate 是否立即執行
總結
當有一些資料需要隨著另外一些資料變化時,建議使用computed。當有一個通用的回應資料變化的時候,要執行一些業務邏輯或非同步操作的時候建議使用watcher
hash模式:在瀏覽器中符號“#”,#以及#後面的字元稱之為hash,用window.location.hash讀取;特點:hash雖然在URL中,但不被包含在HTTP請求中;用來指導瀏覽器動作,對服務端安全無用,hash不會重載入頁面。 hash 模式下,僅hash 符號之前的內容會被包含在請求中,如http://www.xxx.com,因此對於後端來說,即使沒有做到對路由的全覆蓋,也不會返回404錯誤。
history模式:history採用HTML5的新特性;且提供了兩個新方法:pushState(),replaceState()可以對瀏覽器歷史記錄堆疊進行修改,以及popState事件的監聽到狀態變更。 history 模式下,前端的 URL 必須和實際向後端發起請求的 URL 一致,如 http://www.xxx.com/items/id。後端如果缺少 /items/id 的路由處理,將傳回 404 錯誤。
(版本不斷更新,以下的差異有可能不是很正確。我工作中只用到vue,對angular和react不怎麼熟)
1.與AngularJS的區別
相同點:
都支援指令:內建指令和自訂指令;都支援過濾器:內建過濾器和自訂過濾器;都支援雙向資料綁定;都不支援低階瀏覽器。
不同點:
AngularJS的學習成本高,例如增加了Dependency Injection特性,而Vue.js本身提供的API都比較簡單、直覺;在效能上,AngularJS依賴對資料做髒檢查,所以Watcher越多越慢;Vue.js使用基於依賴追蹤的觀察並且使用非同步佇列更新,所有的資料都是獨立觸發的。
2.與React的區別
#相同點:
React採用特殊的JSX語法,Vue.js在組件開發中也推崇編寫.vue特殊文件格式,對文件內容都有一些約定,兩者都需要編譯後使用;中心思想相同:一切都是組件,組件實例之間可以嵌套;都提供合理的鉤子函數,可以讓開發者客製化地去處理需求;都不內建列數AJAX,Route等功能到核心包,而是以插件的方式加載;在組件開發中都支援mixins的特性。
不同點:
React採用的Virtual DOM會對渲染出來的結果做髒檢查;Vue.js在模板中提供了指令,過濾器等,可以非常方便,快速地操作Virtual DOM。
綁定一個原生的click事件: 加native,
其他事件修飾符:stop prevent self
組合鍵:click.ctrl.exact 只有ctrl被按下的時候才觸發
為什麼元件中的data 必須是一個函數,然後return 一個對象,而new Vue 實例裡,data 可以直接是一個物件?
因為元件是用來重複使用的,JS 裡物件是引用關係,這樣作用域沒有隔離,而new Vue 的實例,是不會被重複使用的,因此不存在引用物件的問題
對於Vue是一套漸進式框架的理解
Vue可能有些方面是不如React,不如Angular,但它是漸進的,沒有強主張,你可以在原有大系統的上面,把一兩個組件改用它實現,當jQuery用;也可以整個用它全家桶開發,當Angular用;還可以用它的視圖,搭配你自己設計的整個下層用。你可以在底層資料邏輯的地方用OO和設計模式的那套理念,也可以函數式,都可以,它只是個輕量視圖而已,只做了自己該做的事,沒有做不該做的事,僅此而已。漸進式的意義,我的理解是:沒有多做職責以外的事。
資料驅動與元件化
key
值的作用使用key來給每個節點做一個唯一標識
key的作用主要是為了高效率的更新虛擬DOM。另外vue中在使用相同標籤名稱元素的過渡切換時,也會使用到key屬性,其目的也是為了讓vue可以區分它們,否則vue只會替換其內部屬性而不會觸發過渡效果。
v-for的優先權比v-if高
1、vue中子元件呼叫父元件的方法
第一種方法是直接在子元件中透過this.$parent .event來呼叫父元件的方法。
第二種方法是在子元件裡用$emit
向父元件觸發一個事件,父元件監聽這個事件就行了。
第三種是父元件把方法傳入子元件中,在子元件裡直接呼叫這個方法。
2、vue中父元件呼叫子元件的方法
父元件利用ref屬性運算子元件方法。
父: <child ref="childMethod"></child> 子: method: { test() { alert(1) } } 在父组件里调用test即 this.$refs.childMethod.test()
3、vue元件之間傳值
(1)父元件給子元件傳值:
父元件呼叫子元件的時候動態綁定屬性
<parent :dataList='dataList'></parent>
#子元件定義props接收動態綁定的屬性props: ['dataList']
子元件使用資料
(2)子元件主動取得父子間的屬性與方法:
#在子元件中使用this.$parent.屬性/this.$parent.方法。
(3)子元件給父元件傳值:
一、使用ref屬性
1.父元件呼叫子元件時綁定屬性ref
# < ;parent :ref='parent'>
2.在父元件中使用this.$refs.parent.屬性/this.$refs.parent.方法
二、使用$emit方法
1.子元件呼叫this.$emit('方法名稱',傳值)
2.父元件透過子元件綁定的'方法名稱'取得傳值。
(4)vue頁面層級元件之間傳值
#使用vue-router透過跳躍連結帶參數傳參。
使用本地缓存localStorge。
使用vuex数据管理传值。
(5)说说vue的动态组件。
多个组件通过同一个挂载点进行组件的切换,is的值是哪个组件的名称,那么页面就会显示哪个组件。
(6)keep-alive内置组件的作用
可以让当前组件或者路由不经历创建和销毁,而是进行缓存,凡是被keep-alive组件包裹的组件,除了第一次以外。不会经历创建和销毁阶段的。第一次创建后就会缓存到缓存当
(7)递归组件的用法
组件是可以在它们自己的模板中调用自身的。不过它们只能通过 name 选项来做这件事。首先我们要知道,既然是递归组件,那么一定要有一个结束的条件,否则就会使用组件循环引用,最终出现“max stack size exceeded”的错误,也就是栈溢出。那么,我们可以使用v-if="false"作为递归组件的结束条件。当遇到v-if为false时,组件将不会再进行渲染。
动态路由的创建,主要是使用path属性过程中,使用动态路径参数,以冒号开头,如下:
{ path: '/details/:id' name: 'Details' components: Details }
访问details目录下的所有文件,如果details/a,details/b等,都会映射到Details组件上。
当匹配到/details下的路由时,参数值会被设置到this.$route.params下,所以通过这个属性可以获取动态参数
this.$route.params.id
全局守卫:beforeEach
后置守卫:afterEach
全局解析守卫:beforeResolve
路由独享守卫:beforeEnter
$router为VueRouter的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等。
$route 是路由信息对象||跳转的路由对象,每一个路由都会有一个route对象,是一个局部对象,包含path,params,hash,query,fullPath,matched,name等路由信息参数。
(1)用watch 检测
(2)组件内导航钩子函数
只能使用name,不能使用path
参数不会显示在路径上
浏览器强制刷新参数会被清空
参数会显示在路径上,刷新不会被清空
name 可以使用path路径
1、可维护性会下降,你要想修改数据,你得维护三个地方
2、可读性会下降,因为一个组件里的数据,你根本就看不出来是从哪来的
3、增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。
有五种,分别是 State、 Getter、Mutation 、Action、 Module。
1、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
2、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
3、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
1、getters 可以对State进行计算操作,它就是Store的计算属性
2、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
3、 如果一个状态只在一个组件内使用,是可以不用getters
1、Action 类似于 mutation,不同在于:
2、Action 提交的是 mutation,而不是直接变更状态。
3、Action 可以包含任意异步操作
1、如果請求來的資料是不是要被其他元件公用,只要在請求的元件內使用,就不需要放入vuex 的state。
2、如果被其他地方復用,這個很大幾率上是需要的,如果需要,請將請求放入action裡,方便復用,並包裝成promise返回,在調用處用async await處理傳回的資料。如果不要重複使用這個請求,那麼直接寫在vue檔案裡很方便。
因為vue2.0 object.defineProperty只能劫持物件屬性,無法監控陣列下標的變化,導致透過資料下標添加的元素無法即時回應的弊端。為了解決這個問題,經vue內部處理後,可以使用push()、pop() 、shift()、unshift()、splice()、sort()、reverse()進行hack處理,所以其他陣列屬性也是監測不到,具有一定的限制。
因為object.defineProperty只能劫持物件屬性,因此需要對每個物件的每個屬性進行遍歷。 vue2.0裡是透過遞歸 遍歷data物件來實現對資料的監控的,如果屬性值是物件的話,還需要深度遍歷。
而Vue3.0中的proxy不僅可以代理對象,還可以代理數組,也可以代理動態添加的屬性,有13種劫持操作: get 取得某個key值(接收2個參數,目標值與目標值key值) set 設定某個key值(目標值、目標的key值、要改變的值、改變前的原始值) apply 使用in 運算子判斷某個key是否存在deleteProperty 刪除一個property defineProperty 定義一個新的property
感謝
更多程式相關知識,請造訪:程式設計影片! !
以上是Vue常見面試題摘要(附答案解析)的詳細內容。更多資訊請關注PHP中文網其他相關文章!