1、說說你對 SPA 單頁面的理解,它的優缺點分別是什么?
SPA( single-page application )僅在 Web 頁面初始化時加載相應的 HTML、JavaScript 和 CSS。一旦頁面加載完成,SPA 不會因為用戶的操作而進行頁面的重新加載或跳轉;取而代之的是利用路由機制實現 HTML 內容的變換,UI 與用戶的交互,避免頁面的重新加載。
優點:
- 用戶體驗好、快,內容的改變不需要重新加載整個頁面,避免了不必要的跳轉和重復渲染;
- 基于上面一點,SPA 相對對服務器壓力小;
- 前后端職責分離,架構清晰,前端進行交互邏輯,后端負責數據處理;
缺點:
- 初次加載耗時多:為實現單頁 Web 應用功能及顯示效果,需要在加載頁面的時候將 JavaScript、CSS 統一加載,部分頁面按需加載;
- 前進后退路由管理:由于單頁應用在一個頁面中顯示所有的內容,所以不能使用瀏覽器的前進后退功能,所有的頁面切換需要自己建立堆棧管理;
- SEO 難度較大:由于所有的內容都在一個頁面中動態替換顯示,所以在 SEO 上其有著天然的弱勢。
2、怎樣理解 Vue 的單向數據流?
所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態,從而導致你的應用的數據流向難以理解。
額外的,每次父級組件發生更新時,子組件中所有的 prop 都將會刷新為最新的值。這意味著你不應該在一個子組件內部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發出警告。子組件想修改時,只能通過 $emit 派發一個自定義事件,父組件接收到后,由父組件修改。
有兩種常見的試圖改變一個 prop 的情形 :
- 這個 prop 用來傳遞一個初始值;這個子組件接下來希望將其作為一個本地的 prop 數據來使用。 在這種情況下,最好定義一個本地的 data 屬性并將這個 prop 用作其初始值:
props: ['list'],
data: function () {
return {
counter: this. list
}
}
- 這個 prop 以一種原始的值傳入且需要進行轉換。 在這種情況下,最好使用這個 prop 的值來定義一個計算屬性
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
3、直接給一個數組項賦值,Vue 能檢測到變化嗎?
由于 JavaScript 的限制,Vue 不能檢測到以下數組的變動:
- 當你利用索引直接設置一個數組項時,例如:vm.items[indexOfItem] = newValue
- 當你修改數組的長度時,例如:vm.items.length = newLength
為了解決第一個問題,Vue 提供了以下操作方法:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// vm.$set,Vue.set的一個別名
vm.$set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
為了解決第二個問題,Vue 提供了以下操作方法:
// Array.prototype.splice
vm.items.splice(newLength)
4、Vue 的父組件和子組件生命周期鉤子函數執行順序?
Vue 的父組件和子組件生命周期鉤子函數執行順序可以歸類為以下 4 部分:
- 加載渲染過程
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
- 子組件更新過程
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
- 父組件更新過程
父 beforeUpdate -> 父 updated
- 銷毀過程
父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
5、在什么階段才能訪問操作DOM?
在鉤子函數 mounted 被調用前,Vue 已經將編譯好的模板掛載到頁面上,所以在 mounted 中可以訪問操作 DOM。vue 具體的生命周期示意圖可以參見如下,理解了整個生命周期各個階段的操作,關于生命周期相關的面試題就難不倒你了。

6、父組件可以監聽到子組件的生命周期嗎?
比如有父組件 Parent 和子組件 Child,如果父組件監聽到子組件掛載 mounted 就做一些邏輯處理,可以通過以下寫法實現:
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}
以上需要手動通過 $emit 觸發父組件的事件,更簡單的方式可以在父組件引用子組件時通過 @hook 來監聽即可,如下所示:
// Parent.vue
<Child @hook:mounted="doSomething" ></Child>
doSomething() {
console.log('父組件監聽到 mounted 鉤子函數 ...');
},
// Child.vue
mounted(){
console.log('子組件觸發 mounted 鉤子函數 ...');
},
// 以上輸出順序為:
// 子組件觸發 mounted 鉤子函數 ...
// 父組件監聽到 mounted 鉤子函數 ...
復制代碼
當然 @hook 方法不僅僅是可以監聽 mounted,其它的生命周期事件,例如:created,updated 等都可以監聽。
7、談談你對 keep-alive 的了解?
keep-alive 是 Vue 內置的一個組件,可以使被包含的組件保留狀態,避免重新渲染 ,其有以下特性:
- 一般結合路由和動態組件一起使用,用于緩存組件;
- 提供 include 和 exclude 屬性,兩者都支持字符串或正則表達式, include 表示只有名稱匹配的組件會被緩存,exclude 表示任何名稱匹配的組件都不會被緩存 ,其中 exclude 的優先級比 include 高;
- 對應兩個鉤子函數 activated 和 deactivated ,當組件被激活時,觸發鉤子函數 activated,當組件被移除時,觸發鉤子函數 deactivated。
8、組件中 data 為什么是一個函數?
為什么組件中的 data 必須是一個函數,然后 return 一個對象,而 new Vue 實例里,data 可以直接是一個對象?
因為組件是用來復用的,且 JS 里對象是引用關系,如果組件中 data 是一個對象,那么這樣作用域沒有隔離,子組件中的 data 屬性值會相互影響,如果組件中 data 選項是一個函數,那么每個實例可以維護一份被返回對象的獨立的拷貝,組件實例之間的 data 屬性值不會互相影響;而 new Vue 的實例,是不會被復用的,因此不存在引用對象的問題。
9、Vue 組件間通信有哪幾種方式?
Vue 組件間通信是面試常考的知識點之一,這題有點類似于開放題,你回答出越多方法當然越加分,表明你對 Vue 掌握的越熟練。Vue 組件間通信只要指以下 3 類通信:父子組件通信、隔代組件通信、兄弟組件通信,下面我們分別介紹每種通信方式且會說明此種方法可適用于哪類組件間通信。
(1)props / $emit 適用 父子組件通信
這種方法是 Vue 組件的基礎,相信大部分同學耳聞能詳,所以此處就不舉例展開介紹。
(2)ref 與 $parent / $children 適用 父子組件通信
- ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實例
- $parent / $children:訪問父 / 子實例
(3)EventBus ($emit / $on) 適用于 父子、隔代、兄弟組件通信
這種方法通過一個空的 Vue 實例作為中央事件總線(事件中心),用它來觸發事件和監聽事件,從而實現任何組件間的通信,包括父子、隔代、兄弟組件。
(4)Vuex 適用于 父子、隔代、兄弟組件通信
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。每一個 Vuex 應用的核心就是 store(倉庫)。“store” 基本上就是一個容器,它包含著你的應用中大部分的狀態 ( state )。
- Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那么相應的組件也會相應地得到高效更新。
- 改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化。
10、你使用過 Vuex 嗎?
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。每一個 Vuex 應用的核心就是 store(倉庫)。“store” 基本上就是一個容器,它包含著你的應用中大部分的狀態 ( state )。
(1)Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那么相應的組件也會相應地得到高效更新。
(2)改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化。
主要包括以下幾個模塊:
- State:定義了應用狀態的數據結構,可以在這里設置默認的初始狀態。
- Getter:允許組件從 Store 中獲取數據,mapGetters 輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性。
- Mutation:是唯一更改 store 中狀態的方法,且必須是同步函數。
- Action:用于提交 mutation,而不是直接變更狀態,可以包含任意異步操作。
- Module:允許將單一的 Store 拆分為多個 store 且同時保存在單一的狀態樹中。
11、vue-router 路由模式有幾種?
ue-router 有 2 種路由模式:hash、history
其中,2 種路由模式的說明如下:
- hash: 使用 URL hash 值來作路由。支持所有瀏覽器,包括不支持 HTML5 History Api 的瀏覽器;
- history : 依賴 HTML5 History API 和服務器配置。具體可以查看 HTML5 History 模式;
12、能說下 vue-router 中常用的 hash 和 history 路由模式實現原理嗎?
(1)hash 模式的實現原理
早期的前端路由的實現就是基于 location.hash 來實現的。其實現原理很簡單,location.hash 的值就是 URL 中 # 后面的內容。比如下面這個網站,它的 location.hash 的值為 '#search':
https://www.word.com#search
hash 路由模式的實現主要是基于下面幾個特性:
- URL 中 hash 值只是客戶端的一種狀態,也就是說當向服務器端發出請求時,hash 部分不會被發送;
- hash 值的改變,都會在瀏覽器的訪問歷史中增加一個記錄。因此我們能通過瀏覽器的回退、前進按鈕控制hash 的切換;
- 可以通過 a 標簽,并設置 href 屬性,當用戶點擊這個標簽后,URL 的 hash 值會發生改變;或者使用 JavaScript 來對 loaction.hash 進行賦值,改變 URL 的 hash 值;
- 我們可以使用 hashchange 事件來監聽 hash 值的變化,從而對頁面進行跳轉(渲染)。
(2)history 模式的實現原理
HTML5 提供了 History API 來實現 URL 的變化。其中做最主要的 API 有以下兩個:history.pushState() 和 history.repalceState()。這兩個 API 可以在不進行刷新的情況下,操作瀏覽器的歷史紀錄。唯一不同的是,前者是新增一個歷史記錄,后者是直接替換當前的歷史記錄,如下所示:
window.history.pushState(null, null, path);
window.history.replaceState(null, null, path);
history 路由模式的實現主要基于存在下面幾個特性:
- pushState 和 repalceState 兩個 API 來操作實現 URL 的變化 ;
- 我們可以使用 popstate 事件來監聽 url 的變化,從而對頁面進行跳轉(渲染);
- history.pushState() 或 history.replaceState() 不會觸發 popstate 事件,這時我們需要手動觸發頁面跳轉(渲染)。
13、虛擬 DOM 的優缺點?
優點:
- 保證性能下限: 框架的虛擬 DOM 需要適配任何上層 API 可能產生的操作,它的一些 DOM 操作的實現必須是普適的,所以它的性能并不是最優的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虛擬 DOM 至少可以保證在你不需要手動優化的情況下,依然可以提供還不錯的性能,即保證性能的下限;
- 無需手動操作 DOM: 我們不再需要手動去操作 DOM,只需要寫好 View-Model 的代碼邏輯,框架會根據虛擬 DOM 和 數據雙向綁定,幫我們以可預期的方式更新視圖,極大提高我們的開發效率;
- 跨平臺: 虛擬 DOM 本質上是 JavaScript 對象,而 DOM 與平臺強相關,相比之下虛擬 DOM 可以進行更方便地跨平臺操作,例如服務器渲染、weex 開發等等。
缺點:
- 無法進行極致優化: 雖然虛擬 DOM + 合理的優化,足以應對絕大部分應用的性能需求,但在一些性能要求極高的應用中虛擬 DOM 無法進行針對性的極致優化。
14、你有對 Vue 項目進行哪些優化?
1)代碼層面的優化
- v-if 和 v-show 區分使用場景
- computed 和 watch 區分使用場景
- v-for 遍歷必須為 item 添加 key,且避免同時使用 v-if
- 長列表性能優化
- 事件的銷毀
- 圖片資源懶加載
- 路由懶加載
- 第三方插件的按需引入
- 優化無限列表性能
- 服務端渲染 SSR or 預渲染
(2)Webpack 層面的優化
- Webpack 對圖片進行壓縮
- 減少 ES6 轉為 ES5 的冗余代碼
- 提取公共代碼
- 模板預編譯
- 提取組件的 CSS
- 優化 SourceMap
- 構建結果輸出分析
- Vue 項目的編譯優化
(3)基礎的 Web 技術的優化
- 開啟 gzip 壓縮
- 瀏覽器緩存
- CDN 的使用
- 使用 Chrome Performance 查找性能瓶頸
15、對于即將到來的 vue3.0 特性你有什么了解的嗎?
Vue 3.0 正走在發布的路上,Vue 3.0 的目標是讓 Vue 核心變得更小、更快、更強大,因此 Vue 3.0 增加以下這些新特性:
(1)監測機制的改變
3.0 將帶來基于代理 Proxy 的 observer 實現,提供全語言覆蓋的反應性跟蹤。這消除了 Vue 2 當中基于 Object.defineProperty 的實現所存在的很多限制:
- 只能監測屬性,不能監測對象
- 檢測屬性的添加和刪除;
- 檢測數組索引和長度的變更;
- 支持 Map、Set、WeakMap 和 WeakSet。
新的 observer 還提供了以下特性:
- 用于創建 observable 的公開 API。這為中小規模場景提供了簡單輕量級的跨組件狀態管理解決方案。
- 默認采用惰性觀察。在 2.x 中,不管反應式數據有多大,都會在啟動時被觀察到。如果你的數據集很大,這可能會在應用啟動時帶來明顯的開銷。在 3.x 中,只觀察用于渲染應用程序最初可見部分的數據。
- 更精確的變更通知。在 2.x 中,通過 Vue.set 強制添加新屬性將導致依賴于該對象的 watcher 收到變更通知。在 3.x 中,只有依賴于特定屬性的 watcher 才會收到通知。
- 不可變的 observable:我們可以創建值的“不可變”版本(即使是嵌套屬性),除非系統在內部暫時將其“解禁”。這個機制可用于凍結 prop 傳遞或 Vuex 狀態樹以外的變化。
- 更好的調試功能:我們可以使用新的 renderTracked 和 renderTriggered 鉤子精確地跟蹤組件在什么時候以及為什么重新渲染。
(2)模板
模板方面沒有大的變更,只改了作用域插槽,2.x 的機制導致作用域插槽變了,父組件會重新渲染,而 3.0 把作用域插槽改成了函數的方式,這樣只會影響子組件的重新渲染,提升了渲染的性能。
同時,對于 render 函數的方面,vue3.0 也會進行一系列更改來方便習慣直接使用 api 來生成 vdom 。
(3)對象式的組件聲明方式
vue2.x 中的組件是通過聲明的方式傳入一系列 option,和 TypeScript 的結合需要通過一些裝飾器的方式來做,雖然能實現功能,但是比較麻煩。3.0 修改了組件的聲明方式,改成了類式的寫法,這樣使得和 TypeScript 的結合變得很容易。
此外,vue 的源碼也改用了 TypeScript 來寫。其實當代碼的功能復雜之后,必須有一個靜態類型系統來做一些輔助管理。現在 vue3.0 也全面改用 TypeScript 來重寫了,更是使得對外暴露的 api 更容易結合 TypeScript。靜態類型系統對于復雜代碼的維護確實很有必要。
(4)其它方面的更改
vue3.0 的改變是全面的,上面只涉及到主要的 3 個方面,還有一些其他的更改:
- 支持自定義渲染器,從而使得 weex 可以通過自定義渲染器的方式來擴展,而不是直接 fork 源碼來改的方式。
- 支持 Fragment(多個根節點)和 Protal(在 dom 其他部分渲染組建內容)組件,針對一些特殊的場景做了處理。
- 基于 treeshaking 優化,提供了更多的內置功能。
16、 Vue實現數據雙向綁定的原理:Object.defineProperty()
vue實現數據雙向綁定主要是:采用數據劫持結合發布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變動時發布消息給訂閱者,觸發相應監聽回調。當把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉為 getter/setter。用戶看不到 getter/setter,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。
vue的數據雙向綁定 將MVVM作為數據綁定的入口,整合Observer,Compile和Watcher三者,通過Observer來監聽自己的model的數據變化,通過Compile來解析編譯模板指令(vue中是用來解析 {{}}),最終利用watcher搭起observer和Compile之間的通信橋梁,達到數據變化 —>視圖更新;視圖交互變化(input)—>數據model變更雙向綁定效果。
17、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。
18、vuex是什么?怎么使用?哪種功能場景使用它?
只用來讀取的狀態集中放在store中; 改變狀態的方式是提交mutations,這是個同步的事物; 異步邏輯應該封裝在action中。
在main.js引入store,注入。新建了一個目錄store,….. export 。
場景有:單頁應用中,組件之間的狀態、音樂播放、登錄狀態、加入購物車

state
Vuex 使用單一狀態樹,即每個應用將僅僅包含一個store 實例,但單一狀態樹和模塊化并不沖突。存放的數據狀態,不可以直接修改里面的數據。mutations
mutations定義的方法動態修改Vuex 的 store 中的狀態或數據。getters
類似vue的計算屬性,主要用來過濾一些數據。action
actions可以理解為通過將mutations里面處里數據的方法變成可異步的處理數據的方法,簡單的說就是異步操作數據。view 層通過 store.dispath 來分發 action。
modules
項目特別復雜的時候,可以讓每一個模塊擁有自己的state、mutation、action、getters,使得結構非常清晰,方便管理。
20.css只在當前組件起作用
答:在style標簽中寫入scoped即可 例如:<style scoped></style>
21.$router和router的區別
答:是路由信息對象,包括,,,,,,等路由信息參數。而router是“路由實例”對象包括了路由的跳轉方法,鉤子函數等。
22.vue.js的兩個核心是什么?
答:數據驅動、組件系統
23.v-on 可以綁定多個方法嗎?
答:可以
24.vue中 key 值的作用?
答:當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用“就地復用”策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單復用此處每個元素,并且確保它在特定索引下顯示已被渲染過的每個元素。key的作用主要是為了高效的更新虛擬DOM。
25.什么是vue的計算屬性?
答:在模板中放入太多的邏輯會讓模板過重且難以維護,在需要對數據進行復雜處理,且可能多次使用的情況下,盡量采取計算屬性的方式。好處:①使得數據處理結構清晰;②依賴于數據,數據更新,處理結果自動更新;③計算屬性內部this指向vm實例;④在template調用時,直接寫計算屬性名即可;⑤常用的是getter方法,獲取數據,也可以使用set方法改變數據;⑥相較于methods,不管依賴的數據變不變,methods都會重新計算,但是依賴數據不變的時候computed從緩存中獲取,不會重新計算。
26.怎么定義 vue-router 的動態路由? 怎么獲取傳過來的值
答:在 router 目錄下的 index.js 文件中,對 path 屬性加上 /:id,使用 router 對象的 params.id 獲取。
27.vue優點?
答:輕量級框架:只關注視圖層,是一個構建數據的視圖集合,大小只有幾十kb;
簡單易學:國人開發,中文文檔,不存在語言障礙 ,易于理解和學習;
雙向數據綁定:保留了angular的特點,在數據操作方面更為簡單;
組件化:保留了react的優點,實現了html的封裝和重用,在構建單頁面應用方面有著獨特的優勢;
視圖,數據,結構分離:使數據的更改更為簡單,不需要進行邏輯代碼的修改,只需要操作數據就能完成相關操作;
虛擬DOM:dom操作是非常耗費性能的, 不再使用原生的dom操作節點,極大解放dom操作,但具體操作的還是dom不過是換了另一種方式;
運行速度更快:相比較與react而言,同樣是操作虛擬dom,就性能而言,vue存在很大的優勢。
28.如何獲取dom?
答:ref="domName" 用法:this.$refs.domName
29. vue-loader是什么?使用它的用途有哪些?
答:vue文件的一個加載器,將template/js/style轉換成js模塊。
用途:js可以寫es6、style樣式可以scss或less、template可以加jade等
30.axios及安裝?
答:請求后臺資源的模塊。npm install axios --save裝好,
js中使用import進來,然后.get或.post。返回在.then函數中如果成功,失敗則是在.catch函數中。
31.請說出vue.cli項目中src目錄每個文件夾和文件的用法?
答:assets文件夾是放靜態資源;components是放組件;router是定義路由相關的配置; app.vue是一個應用主組件;main.js是入口文件。
32.$nextTick的使用
答:當你修改了data的值然后馬上獲取這個dom元素的值,是不能獲取到更新后的值,
你需要使用$nextTick這個回調,讓修改后的data值渲染更新到dom元素之后在獲取,才能成功。
33.assets和static的區別
答:相同點:assets和static兩個都是存放靜態資源文件。項目中所需要的資源文件圖片,字體圖標,樣式文件等都可以放在這兩個文件下,這是相同點
不相同點:assets中存放的靜態資源文件在項目打包時,也就是運行npm run build時會將assets中放置的靜態資源文件進行打包上傳,所謂打包簡單點可以理解為壓縮體積,代碼格式化。而壓縮后的靜態資源文件最終也都會放置在static文件中跟著index.html一同上傳至服務器。static中放置的靜態資源文件就不會要走打包壓縮格式化等流程,而是直接進入打包好的目錄,直接上傳至服務器。因為避免了壓縮直接進行上傳,在打包時會提高一定的效率,但是static中的資源文件由于沒有進行壓縮等操作,所以文件的體積也就相對于assets中打包后的文件提交較大點。在服務器中就會占據更大的空間。
建議:將項目中template需要的樣式文件js文件等都可以放置在assets中,走打包這一流程。減少體積。而項目中引入的第三方的資源文件如iconfoont.css等文件可以放置在static中,因為這些引入的第三方文件已經經過處理,我們不再需要處理,直接上傳。
34.vue和jQuery的區別
答:jQuery是使用選擇器($)選取DOM對象,對其進行賦值、取值、事件綁定等操作,其實和原生的HTML的區別只在于可以更方便的選取和操作DOM對象,而數據和界面是在一起的。比如需要獲取label標簽的內容:$("lable").val();,它還是依賴DOM元素的值。
Vue則是通過Vue對象將數據和View完全分離開來了。對數據進行操作不再需要引用相應的DOM對象,可以說數據和View是分離的,他們通過Vue對象這個vm實現相互的綁定。這就是傳說中的MVVM。
35. 引進組件的步驟
答: 在template中引入組件;
在script的第一行用import引入路徑;
用component中寫上組件名稱。
36.Vue-router跳轉和location.href有什么區別
答:使用location.href='/url'來跳轉,簡單方便,但是刷新了頁面;
使用history.pushState('/url'),無刷新頁面,靜態跳轉;
引進router,然后使用router.push('/url')來跳轉,使用了diff算法,實現了按需加載,減少了dom的消耗。
其實使用router跳轉和使用history.pushState()沒什么差別的,因為vue-router就是用了history.pushState(),尤其是在history模式下。
37. vue slot
答:簡單來說,假如父組件需要在子組件內放一些DOM,那么這些DOM是顯示、不顯示、在哪個地方顯示、如何顯示,就是slot分發負責的活。
38.axios的特點有哪些
答:從瀏覽器中創建XMLHttpRequests;
node.js創建http請求;
支持Promise API;
攔截請求和響應;
轉換請求數據和響應數據;
取消請求;
自動換成json。
axios中的發送字段的參數是data跟params兩個,兩者的區別在于params是跟請求地址一起發送的,data的作為一個請求體進行發送
params一般適用于get請求,data一般適用于post put 請求。
39.你們vue項目是打包了一個js文件,一個css文件,還是有多個文件?
答:根據vue-cli腳手架規范,一個js文件,一個CSS文件。
40.Vue里面router-link在電腦上有用,在安卓上沒反應怎么解決?
答:Vue路由在Android機上有問題,babel問題,安裝babel polypill插件解決
41.Vue2中注冊在router-link上事件無效解決方法
答: 使用@click.native。原因:router-link會阻止click事件,.native指直接監聽一個原生事件。
42.params和query的區別
答:用法:query要用path來引入,params要用name來引入,接收參數都是類似的,分別是this.$route.query.name和this.$route.params.name。
url地址顯示:query更加類似于我們ajax中get傳參,params則類似于post,說的再簡單一點,前者在瀏覽器地址欄中顯示參數,后者則不顯示
注意點:query刷新不會丟失query里面的數據
params刷新 會 丟失 params里面的數據。
43.vue初始化頁面閃動問題
答:使用vue開發時,在vue初始化之前,由于div是不歸vue管的,所以我們寫的代碼在還沒有解析的情況下會容易出現花屏現象,看到類似于{{message}}的字樣,雖然一般情況下這個時間很短暫,但是我們還是有必要讓解決這個問題的。
首先:在css里加上[v-cloak] {
display: none;
}。
如果沒有徹底解決問題,則在根元素加上style="display: none;" :style="{display: 'block'}"
44.vue更新數組時觸發視圖更新的方法
答:push();pop();shift();unshift();splice(); sort();reverse()
45.watch和computed的區別以及使用場景?
區別:
watch中的函數是不需要調用的
computed內部的函數調用的時候不需要加()
watch 屬性監聽 監聽屬性的變化
computed:計算屬性 通過屬性計算而得來的屬性
watch需要在數據變化時執行異步或開銷較大的操作時使用
computed 屬性的結果會被緩存,除非依賴的響應式屬性變化才會重新計算。
主要當作屬性來使用。
使用場景:
computed
當一個屬性受多個屬性影響的時候就需要用到computed
最典型的例子: 購物車商品結算的時候
watch
當一條數據影響多條數據的時候就需要用watch
搜索數據
46 導航守衛
1.全局守衛
全局前置守衛
router.beforeEach((to, from, next) => {
// ...
})
全局后置守衛
router.afterEach((to, from) => {
// ...
})
2.路由獨享守衛
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
3.組件內的守衛
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能!獲取組件實例 `this`
// 因為當守衛執行前,組件實例還沒被創建
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被復用時調用
// 舉例來說,對于一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由于會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鉤子就會在這個情況下被調用。
// 可以訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用
// 可以訪問組件實例 `this`
}
}
47 路由滾動行為
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滾動到哪個的位置
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
})
48.axios是什么?怎么使用?
答案: 請求后臺資源的模塊
使用npm install axios -s 來安裝
在main.js入口文件中引用:import axios from {axios}
將axios掛載到vue實例上:vue.prototype.$axios = axios
在config文件夾中的index.js中的Dev中填寫
ProxyTable:{
‘/api’:{
Target:’代理服務器的目標地址’,
changeOrigin: true,
PathRewrite: {“^/api”:” ”}
}
}
在需要調用后臺資源的組件中進行使用this.$axios({
Url: ‘/api/地址’,
Method:’post’,//post請求必須設置
Params:{要傳的參數}//post要將params設置為data
}).then(res=>{}).catch(err=>{})
49.如何解決跨域問題
答案:在config文件夾中的index.js中的Dev中填寫
ProxyTable:{
‘/api’:{
Target:’代理服務器的目標地址’,
changeOrigin: true,
PathRewrite: {“^/api”:” ”}
}
}
50.axios面試題
1、axios的特點有哪些?
答:
一、Axios 是一個基于 promise 的 HTTP 庫,支持promise所有的API
二、它可以攔截請求和響應
三、它可以轉換請求數據和響應數據,并對響應回來的內容自動轉換成 JSON類型的數據
四、安全性更高,客戶端支持防御 XSRF
2、axios有哪些常用方法?
答:
一、axios.get(url[, config]) //get請求用于列表和信息查詢
二、axios.delete(url[, config]) //刪除
三、axios.post(url[, data[, config]]) //post請求用于信息的添加
四、axios.put(url[, data[, config]]) //更新操作
3、說下你了解的axios相關配置屬性?
答:
`url`是用于請求的服務器URL
`method`是創建請求時使用的方法,默認是get
`baseURL`將自動加在`url`前面,除非`url`是一個絕對URL。它可以通過設置一個`baseURL`便于為axios實例的方法傳遞相對URL
`transformRequest`允許在向服務器發送前,修改請求數據,只能用在'PUT','POST'和'PATCH'這幾個請求方法
`headers`是即將被發送的自定義請求頭
headers:{'X-Requested-With':'XMLHttpRequest'},
`params`是即將與請求一起發送的URL參數,必須是一個無格式對象(plainobject)或URLSearchParams對象
params:{
ID:12345
},
`auth`表示應該使用HTTP基礎驗證,并提供憑據
這將設置一個`Authorization`頭,覆寫掉現有的任意使用`headers`設置的自定義`Authorization`頭
auth:{
username:'janedoe',
password:'s00pers3cret'
},
'proxy'定義代理服務器的主機名稱和端口
`auth`表示HTTP基礎驗證應當用于連接代理,并提供憑據
這將會設置一個`Proxy-Authorization`頭,覆寫掉已有的通過使用`header`設置的自定義`Proxy-Authorization`頭。
proxy:{
host:'127.0.0.1',
port:9000,
auth::{
username:'mikeymike',
password:'rapunz3l'
}
},
4、請求攔截器
請求攔截器的作用是在請求發送前進行一些操作,例如在每個請求體里加上token,統一做了處理如果以后要改也非常容易。
axios.interceptors.request.use(function (config) {
// 在發送請求之前做些什么,例如加入token
.......
return config;
}, function (error) {
// 對請求錯誤做些什么
return Promise.reject(error);
});
5、響應攔截器
響應攔截器的作用是在接收到響應后進行一些操作,例如在服務器返回登錄狀態失效,需要重新登錄的時候,跳轉到登錄頁
axios.interceptors.response.use(function (response) {
// 在接收響應做些什么,例如跳轉到登錄頁
......
return response;
}, function (error) {
// 對響應錯誤做點什么
return Promise.reject(error);
});