iframe vue 前进 后退_vue常见面试题
1、說說你對 SPA 單頁面的理解,它的優(yōu)缺點(diǎn)分別是什么?
SPA( single-page application )僅在 Web 頁面初始化時(shí)加載相應(yīng)的 HTML、JavaScript 和 CSS。一旦頁面加載完成,SPA 不會(huì)因?yàn)橛脩舻牟僮鞫M(jìn)行頁面的重新加載或跳轉(zhuǎn);取而代之的是利用路由機(jī)制實(shí)現(xiàn) HTML 內(nèi)容的變換,UI 與用戶的交互,避免頁面的重新加載。
優(yōu)點(diǎn):
- 用戶體驗(yàn)好、快,內(nèi)容的改變不需要重新加載整個(gè)頁面,避免了不必要的跳轉(zhuǎn)和重復(fù)渲染;
- 基于上面一點(diǎn),SPA 相對對服務(wù)器壓力小;
- 前后端職責(zé)分離,架構(gòu)清晰,前端進(jìn)行交互邏輯,后端負(fù)責(zé)數(shù)據(jù)處理;
缺點(diǎn):
- 初次加載耗時(shí)多:為實(shí)現(xiàn)單頁 Web 應(yīng)用功能及顯示效果,需要在加載頁面的時(shí)候?qū)?JavaScript、CSS 統(tǒng)一加載,部分頁面按需加載;
- 前進(jìn)后退路由管理:由于單頁應(yīng)用在一個(gè)頁面中顯示所有的內(nèi)容,所以不能使用瀏覽器的前進(jìn)后退功能,所有的頁面切換需要自己建立堆棧管理;
- SEO 難度較大:由于所有的內(nèi)容都在一個(gè)頁面中動(dòng)態(tài)替換顯示,所以在 SEO 上其有著天然的弱勢。
2、怎樣理解 Vue 的單向數(shù)據(jù)流?
所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級 prop 的更新會(huì)向下流動(dòng)到子組件中,但是反過來則不行。這樣會(huì)防止從子組件意外改變父級組件的狀態(tài),從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。
額外的,每次父級組件發(fā)生更新時(shí),子組件中所有的 prop 都將會(huì)刷新為最新的值。這意味著你不應(yīng)該在一個(gè)子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會(huì)在瀏覽器的控制臺中發(fā)出警告。子組件想修改時(shí),只能通過 $emit 派發(fā)一個(gè)自定義事件,父組件接收到后,由父組件修改。
有兩種常見的試圖改變一個(gè) prop 的情形 :
- 這個(gè) prop 用來傳遞一個(gè)初始值;這個(gè)子組件接下來希望將其作為一個(gè)本地的 prop 數(shù)據(jù)來使用。 在這種情況下,最好定義一個(gè)本地的 data 屬性并將這個(gè) prop 用作其初始值:
props: ['list'],
data: function () {
return {
counter: this. list
}
}
- 這個(gè) prop 以一種原始的值傳入且需要進(jìn)行轉(zhuǎn)換。 在這種情況下,最好使用這個(gè) prop 的值來定義一個(gè)計(jì)算屬性
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
3、直接給一個(gè)數(shù)組項(xiàng)賦值,Vue 能檢測到變化嗎?
由于 JavaScript 的限制,Vue 不能檢測到以下數(shù)組的變動(dòng):
- 當(dāng)你利用索引直接設(shè)置一個(gè)數(shù)組項(xiàng)時(shí),例如:vm.items[indexOfItem] = newValue
- 當(dāng)你修改數(shù)組的長度時(shí),例如:vm.items.length = newLength
為了解決第一個(gè)問題,Vue 提供了以下操作方法:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// vm.$set,Vue.set的一個(gè)別名
vm.$set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
為了解決第二個(gè)問題,Vue 提供了以下操作方法:
// Array.prototype.splice
vm.items.splice(newLength)
4、Vue 的父組件和子組件生命周期鉤子函數(shù)執(zhí)行順序?
Vue 的父組件和子組件生命周期鉤子函數(shù)執(zhí)行順序可以歸類為以下 4 部分:
- 加載渲染過程
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
- 子組件更新過程
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
- 父組件更新過程
父 beforeUpdate -> 父 updated
- 銷毀過程
父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
5、在什么階段才能訪問操作DOM?
在鉤子函數(shù) mounted 被調(diào)用前,Vue 已經(jīng)將編譯好的模板掛載到頁面上,所以在 mounted 中可以訪問操作 DOM。vue 具體的生命周期示意圖可以參見如下,理解了整個(gè)生命周期各個(gè)階段的操作,關(guān)于生命周期相關(guān)的面試題就難不倒你了。
6、父組件可以監(jiān)聽到子組件的生命周期嗎?
比如有父組件 Parent 和子組件 Child,如果父組件監(jiān)聽到子組件掛載 mounted 就做一些邏輯處理,可以通過以下寫法實(shí)現(xiàn):
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}
以上需要手動(dòng)通過 $emit 觸發(fā)父組件的事件,更簡單的方式可以在父組件引用子組件時(shí)通過 @hook 來監(jiān)聽即可,如下所示:
// Parent.vue
<Child @hook:mounted="doSomething" ></Child>
doSomething() {
console.log('父組件監(jiān)聽到 mounted 鉤子函數(shù) ...');
},
// Child.vue
mounted(){
console.log('子組件觸發(fā) mounted 鉤子函數(shù) ...');
},
// 以上輸出順序?yàn)?#xff1a;
// 子組件觸發(fā) mounted 鉤子函數(shù) ...
// 父組件監(jiān)聽到 mounted 鉤子函數(shù) ...
復(fù)制代碼
當(dāng)然 @hook 方法不僅僅是可以監(jiān)聽 mounted,其它的生命周期事件,例如:created,updated 等都可以監(jiān)聽。
7、談?wù)勀銓?keep-alive 的了解?
keep-alive 是 Vue 內(nèi)置的一個(gè)組件,可以使被包含的組件保留狀態(tài),避免重新渲染 ,其有以下特性:
- 一般結(jié)合路由和動(dòng)態(tài)組件一起使用,用于緩存組件;
- 提供 include 和 exclude 屬性,兩者都支持字符串或正則表達(dá)式, include 表示只有名稱匹配的組件會(huì)被緩存,exclude 表示任何名稱匹配的組件都不會(huì)被緩存 ,其中 exclude 的優(yōu)先級比 include 高;
- 對應(yīng)兩個(gè)鉤子函數(shù) activated 和 deactivated ,當(dāng)組件被激活時(shí),觸發(fā)鉤子函數(shù) activated,當(dāng)組件被移除時(shí),觸發(fā)鉤子函數(shù) deactivated。
8、組件中 data 為什么是一個(gè)函數(shù)?
為什么組件中的 data 必須是一個(gè)函數(shù),然后 return 一個(gè)對象,而 new Vue 實(shí)例里,data 可以直接是一個(gè)對象?
因?yàn)榻M件是用來復(fù)用的,且 JS 里對象是引用關(guān)系,如果組件中 data 是一個(gè)對象,那么這樣作用域沒有隔離,子組件中的 data 屬性值會(huì)相互影響,如果組件中 data 選項(xiàng)是一個(gè)函數(shù),那么每個(gè)實(shí)例可以維護(hù)一份被返回對象的獨(dú)立的拷貝,組件實(shí)例之間的 data 屬性值不會(huì)互相影響;而 new Vue 的實(shí)例,是不會(huì)被復(fù)用的,因此不存在引用對象的問題。
9、Vue 組件間通信有哪幾種方式?
Vue 組件間通信是面試常考的知識點(diǎn)之一,這題有點(diǎn)類似于開放題,你回答出越多方法當(dāng)然越加分,表明你對 Vue 掌握的越熟練。Vue 組件間通信只要指以下 3 類通信:父子組件通信、隔代組件通信、兄弟組件通信,下面我們分別介紹每種通信方式且會(huì)說明此種方法可適用于哪類組件間通信。
(1)props / $emit 適用 父子組件通信
這種方法是 Vue 組件的基礎(chǔ),相信大部分同學(xué)耳聞能詳,所以此處就不舉例展開介紹。
(2)ref 與 $parent / $children 適用 父子組件通信
- ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實(shí)例
- $parent / $children:訪問父 / 子實(shí)例
(3)EventBus ($emit / $on) 適用于 父子、隔代、兄弟組件通信
這種方法通過一個(gè)空的 Vue 實(shí)例作為中央事件總線(事件中心),用它來觸發(fā)事件和監(jiān)聽事件,從而實(shí)現(xiàn)任何組件間的通信,包括父子、隔代、兄弟組件。
(4)Vuex 適用于 父子、隔代、兄弟組件通信
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。每一個(gè) Vuex 應(yīng)用的核心就是 store(倉庫)。“store” 基本上就是一個(gè)容器,它包含著你的應(yīng)用中大部分的狀態(tài) ( state )。
- Vuex 的狀態(tài)存儲是響應(yīng)式的。當(dāng) Vue 組件從 store 中讀取狀態(tài)的時(shí)候,若 store 中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)相應(yīng)地得到高效更新。
- 改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個(gè)狀態(tài)的變化。
10、你使用過 Vuex 嗎?
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。每一個(gè) Vuex 應(yīng)用的核心就是 store(倉庫)。“store” 基本上就是一個(gè)容器,它包含著你的應(yīng)用中大部分的狀態(tài) ( state )。
(1)Vuex 的狀態(tài)存儲是響應(yīng)式的。當(dāng) Vue 組件從 store 中讀取狀態(tài)的時(shí)候,若 store 中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)相應(yīng)地得到高效更新。
(2)改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個(gè)狀態(tài)的變化。
主要包括以下幾個(gè)模塊:
- State:定義了應(yīng)用狀態(tài)的數(shù)據(jù)結(jié)構(gòu),可以在這里設(shè)置默認(rèn)的初始狀態(tài)。
- Getter:允許組件從 Store 中獲取數(shù)據(jù),mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性。
- Mutation:是唯一更改 store 中狀態(tài)的方法,且必須是同步函數(shù)。
- Action:用于提交 mutation,而不是直接變更狀態(tài),可以包含任意異步操作。
- Module:允許將單一的 Store 拆分為多個(gè) store 且同時(shí)保存在單一的狀態(tài)樹中。
11、vue-router 路由模式有幾種?
ue-router 有 2 種路由模式:hash、history
其中,2 種路由模式的說明如下:
- hash: 使用 URL hash 值來作路由。支持所有瀏覽器,包括不支持 HTML5 History Api 的瀏覽器;
- history : 依賴 HTML5 History API 和服務(wù)器配置。具體可以查看 HTML5 History 模式;
12、能說下 vue-router 中常用的 hash 和 history 路由模式實(shí)現(xiàn)原理嗎?
(1)hash 模式的實(shí)現(xiàn)原理
早期的前端路由的實(shí)現(xiàn)就是基于 location.hash 來實(shí)現(xiàn)的。其實(shí)現(xiàn)原理很簡單,location.hash 的值就是 URL 中 # 后面的內(nèi)容。比如下面這個(gè)網(wǎng)站,它的 location.hash 的值為 '#search':
https://www.word.com#search
hash 路由模式的實(shí)現(xiàn)主要是基于下面幾個(gè)特性:
- URL 中 hash 值只是客戶端的一種狀態(tài),也就是說當(dāng)向服務(wù)器端發(fā)出請求時(shí),hash 部分不會(huì)被發(fā)送;
- hash 值的改變,都會(huì)在瀏覽器的訪問歷史中增加一個(gè)記錄。因此我們能通過瀏覽器的回退、前進(jìn)按鈕控制hash 的切換;
- 可以通過 a 標(biāo)簽,并設(shè)置 href 屬性,當(dāng)用戶點(diǎn)擊這個(gè)標(biāo)簽后,URL 的 hash 值會(huì)發(fā)生改變;或者使用 JavaScript 來對 loaction.hash 進(jìn)行賦值,改變 URL 的 hash 值;
- 我們可以使用 hashchange 事件來監(jiān)聽 hash 值的變化,從而對頁面進(jìn)行跳轉(zhuǎn)(渲染)。
(2)history 模式的實(shí)現(xiàn)原理
HTML5 提供了 History API 來實(shí)現(xiàn) URL 的變化。其中做最主要的 API 有以下兩個(gè):history.pushState() 和 history.repalceState()。這兩個(gè) API 可以在不進(jìn)行刷新的情況下,操作瀏覽器的歷史紀(jì)錄。唯一不同的是,前者是新增一個(gè)歷史記錄,后者是直接替換當(dāng)前的歷史記錄,如下所示:
window.history.pushState(null, null, path);
window.history.replaceState(null, null, path);
history 路由模式的實(shí)現(xiàn)主要基于存在下面幾個(gè)特性:
- pushState 和 repalceState 兩個(gè) API 來操作實(shí)現(xiàn) URL 的變化 ;
- 我們可以使用 popstate 事件來監(jiān)聽 url 的變化,從而對頁面進(jìn)行跳轉(zhuǎn)(渲染);
- history.pushState() 或 history.replaceState() 不會(huì)觸發(fā) popstate 事件,這時(shí)我們需要手動(dòng)觸發(fā)頁面跳轉(zhuǎn)(渲染)。
13、虛擬 DOM 的優(yōu)缺點(diǎn)?
優(yōu)點(diǎn):
- 保證性能下限: 框架的虛擬 DOM 需要適配任何上層 API 可能產(chǎn)生的操作,它的一些 DOM 操作的實(shí)現(xiàn)必須是普適的,所以它的性能并不是最優(yōu)的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虛擬 DOM 至少可以保證在你不需要手動(dòng)優(yōu)化的情況下,依然可以提供還不錯(cuò)的性能,即保證性能的下限;
- 無需手動(dòng)操作 DOM: 我們不再需要手動(dòng)去操作 DOM,只需要寫好 View-Model 的代碼邏輯,框架會(huì)根據(jù)虛擬 DOM 和 數(shù)據(jù)雙向綁定,幫我們以可預(yù)期的方式更新視圖,極大提高我們的開發(fā)效率;
- 跨平臺: 虛擬 DOM 本質(zhì)上是 JavaScript 對象,而 DOM 與平臺強(qiáng)相關(guān),相比之下虛擬 DOM 可以進(jìn)行更方便地跨平臺操作,例如服務(wù)器渲染、weex 開發(fā)等等。
缺點(diǎn):
- 無法進(jìn)行極致優(yōu)化: 雖然虛擬 DOM + 合理的優(yōu)化,足以應(yīng)對絕大部分應(yīng)用的性能需求,但在一些性能要求極高的應(yīng)用中虛擬 DOM 無法進(jìn)行針對性的極致優(yōu)化。
14、你有對 Vue 項(xiàng)目進(jìn)行哪些優(yōu)化?
1)代碼層面的優(yōu)化
- v-if 和 v-show 區(qū)分使用場景
- computed 和 watch 區(qū)分使用場景
- v-for 遍歷必須為 item 添加 key,且避免同時(shí)使用 v-if
- 長列表性能優(yōu)化
- 事件的銷毀
- 圖片資源懶加載
- 路由懶加載
- 第三方插件的按需引入
- 優(yōu)化無限列表性能
- 服務(wù)端渲染 SSR or 預(yù)渲染
(2)Webpack 層面的優(yōu)化
- Webpack 對圖片進(jìn)行壓縮
- 減少 ES6 轉(zhuǎn)為 ES5 的冗余代碼
- 提取公共代碼
- 模板預(yù)編譯
- 提取組件的 CSS
- 優(yōu)化 SourceMap
- 構(gòu)建結(jié)果輸出分析
- Vue 項(xiàng)目的編譯優(yōu)化
(3)基礎(chǔ)的 Web 技術(shù)的優(yōu)化
- 開啟 gzip 壓縮
- 瀏覽器緩存
- CDN 的使用
- 使用 Chrome Performance 查找性能瓶頸
15、對于即將到來的 vue3.0 特性你有什么了解的嗎?
Vue 3.0 正走在發(fā)布的路上,Vue 3.0 的目標(biāo)是讓 Vue 核心變得更小、更快、更強(qiáng)大,因此 Vue 3.0 增加以下這些新特性:
(1)監(jiān)測機(jī)制的改變
3.0 將帶來基于代理 Proxy 的 observer 實(shí)現(xiàn),提供全語言覆蓋的反應(yīng)性跟蹤。這消除了 Vue 2 當(dāng)中基于 Object.defineProperty 的實(shí)現(xiàn)所存在的很多限制:
- 只能監(jiān)測屬性,不能監(jiān)測對象
- 檢測屬性的添加和刪除;
- 檢測數(shù)組索引和長度的變更;
- 支持 Map、Set、WeakMap 和 WeakSet。
新的 observer 還提供了以下特性:
- 用于創(chuàng)建 observable 的公開 API。這為中小規(guī)模場景提供了簡單輕量級的跨組件狀態(tài)管理解決方案。
- 默認(rèn)采用惰性觀察。在 2.x 中,不管反應(yīng)式數(shù)據(jù)有多大,都會(huì)在啟動(dòng)時(shí)被觀察到。如果你的數(shù)據(jù)集很大,這可能會(huì)在應(yīng)用啟動(dòng)時(shí)帶來明顯的開銷。在 3.x 中,只觀察用于渲染應(yīng)用程序最初可見部分的數(shù)據(jù)。
- 更精確的變更通知。在 2.x 中,通過 Vue.set 強(qiáng)制添加新屬性將導(dǎo)致依賴于該對象的 watcher 收到變更通知。在 3.x 中,只有依賴于特定屬性的 watcher 才會(huì)收到通知。
- 不可變的 observable:我們可以創(chuàng)建值的“不可變”版本(即使是嵌套屬性),除非系統(tǒng)在內(nèi)部暫時(shí)將其“解禁”。這個(gè)機(jī)制可用于凍結(jié) prop 傳遞或 Vuex 狀態(tài)樹以外的變化。
- 更好的調(diào)試功能:我們可以使用新的 renderTracked 和 renderTriggered 鉤子精確地跟蹤組件在什么時(shí)候以及為什么重新渲染。
(2)模板
模板方面沒有大的變更,只改了作用域插槽,2.x 的機(jī)制導(dǎo)致作用域插槽變了,父組件會(huì)重新渲染,而 3.0 把作用域插槽改成了函數(shù)的方式,這樣只會(huì)影響子組件的重新渲染,提升了渲染的性能。
同時(shí),對于 render 函數(shù)的方面,vue3.0 也會(huì)進(jìn)行一系列更改來方便習(xí)慣直接使用 api 來生成 vdom 。
(3)對象式的組件聲明方式
vue2.x 中的組件是通過聲明的方式傳入一系列 option,和 TypeScript 的結(jié)合需要通過一些裝飾器的方式來做,雖然能實(shí)現(xiàn)功能,但是比較麻煩。3.0 修改了組件的聲明方式,改成了類式的寫法,這樣使得和 TypeScript 的結(jié)合變得很容易。
此外,vue 的源碼也改用了 TypeScript 來寫。其實(shí)當(dāng)代碼的功能復(fù)雜之后,必須有一個(gè)靜態(tài)類型系統(tǒng)來做一些輔助管理。現(xiàn)在 vue3.0 也全面改用 TypeScript 來重寫了,更是使得對外暴露的 api 更容易結(jié)合 TypeScript。靜態(tài)類型系統(tǒng)對于復(fù)雜代碼的維護(hù)確實(shí)很有必要。
(4)其它方面的更改
vue3.0 的改變是全面的,上面只涉及到主要的 3 個(gè)方面,還有一些其他的更改:
- 支持自定義渲染器,從而使得 weex 可以通過自定義渲染器的方式來擴(kuò)展,而不是直接 fork 源碼來改的方式。
- 支持 Fragment(多個(gè)根節(jié)點(diǎn))和 Protal(在 dom 其他部分渲染組建內(nèi)容)組件,針對一些特殊的場景做了處理。
- 基于 treeshaking 優(yōu)化,提供了更多的內(nèi)置功能。
16、 Vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定的原理:Object.defineProperty()
vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個(gè)屬性的setter,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)監(jiān)聽回調(diào)。當(dāng)把一個(gè)普通 Javascript 對象傳給 Vue 實(shí)例來作為它的 data 選項(xiàng)時(shí),Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉(zhuǎn)為 getter/setter。用戶看不到 getter/setter,但是在內(nèi)部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時(shí)通知變化。
vue的數(shù)據(jù)雙向綁定 將MVVM作為數(shù)據(jù)綁定的入口,整合Observer,Compile和Watcher三者,通過Observer來監(jiān)聽自己的model的數(shù)據(jù)變化,通過Compile來解析編譯模板指令(vue中是用來解析 {{}}),最終利用watcher搭起observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 —>視圖更新;視圖交互變化(input)—>數(shù)據(jù)model變更雙向綁定效果。
17、Vue與Angular以及React的區(qū)別?
1.與AngularJS的區(qū)別
相同點(diǎn):
都支持指令:內(nèi)置指令和自定義指令;都支持過濾器:內(nèi)置過濾器和自定義過濾器;都支持雙向數(shù)據(jù)綁定;都不支持低端瀏覽器。
不同點(diǎn):
AngularJS的學(xué)習(xí)成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比較簡單、直觀;在性能上,AngularJS依賴對數(shù)據(jù)做臟檢查,所以Watcher越多越慢;Vue.js使用基于依賴追蹤的觀察并且使用異步隊(duì)列更新,所有的數(shù)據(jù)都是獨(dú)立觸發(fā)的。
2.與React的區(qū)別
相同點(diǎn):
React采用特殊的JSX語法,Vue.js在組件開發(fā)中也推崇編寫.vue特殊文件格式,對文件內(nèi)容都有一些約定,兩者都需要編譯后使用;中心思想相同:一切都是組件,組件實(shí)例之間可以嵌套;都提供合理的鉤子函數(shù),可以讓開發(fā)者定制化地去處理需求;都不內(nèi)置列數(shù)AJAX,Route等功能到核心包,而是以插件的方式加載;在組件開發(fā)中都支持mixins的特性。
不同點(diǎn):
React采用的Virtual DOM會(huì)對渲染出來的結(jié)果做臟檢查;Vue.js在模板中提供了指令,過濾器等,可以非常方便,快捷地操作Virtual DOM。
18、vuex是什么?怎么使用?哪種功能場景使用它?
只用來讀取的狀態(tài)集中放在store中; 改變狀態(tài)的方式是提交mutations,這是個(gè)同步的事物; 異步邏輯應(yīng)該封裝在action中。
在main.js引入store,注入。新建了一個(gè)目錄store,….. export 。
場景有:單頁應(yīng)用中,組件之間的狀態(tài)、音樂播放、登錄狀態(tài)、加入購物車
state
Vuex 使用單一狀態(tài)樹,即每個(gè)應(yīng)用將僅僅包含一個(gè)store 實(shí)例,但單一狀態(tài)樹和模塊化并不沖突。存放的數(shù)據(jù)狀態(tài),不可以直接修改里面的數(shù)據(jù)。mutations
mutations定義的方法動(dòng)態(tài)修改Vuex 的 store 中的狀態(tài)或數(shù)據(jù)。getters
類似vue的計(jì)算屬性,主要用來過濾一些數(shù)據(jù)。action
actions可以理解為通過將mutations里面處里數(shù)據(jù)的方法變成可異步的處理數(shù)據(jù)的方法,簡單的說就是異步操作數(shù)據(jù)。view 層通過 store.dispath 來分發(fā) action。
modules
項(xiàng)目特別復(fù)雜的時(shí)候,可以讓每一個(gè)模塊擁有自己的state、mutation、action、getters,使得結(jié)構(gòu)非常清晰,方便管理。
20.css只在當(dāng)前組件起作用
答:在style標(biāo)簽中寫入scoped即可 例如:<style scoped></style>
21.$router和router的區(qū)別
答:是路由信息對象,包括,,,,,,等路由信息參數(shù)。而router是“路由實(shí)例”對象包括了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等。
22.vue.js的兩個(gè)核心是什么?
答:數(shù)據(jù)驅(qū)動(dòng)、組件系統(tǒng)
23.v-on 可以綁定多個(gè)方法嗎?
答:可以
24.vue中 key 值的作用?
答:當(dāng) Vue.js 用 v-for 正在更新已渲染過的元素列表時(shí),它默認(rèn)用“就地復(fù)用”策略。如果數(shù)據(jù)項(xiàng)的順序被改變,Vue 將不會(huì)移動(dòng) DOM 元素來匹配數(shù)據(jù)項(xiàng)的順序, 而是簡單復(fù)用此處每個(gè)元素,并且確保它在特定索引下顯示已被渲染過的每個(gè)元素。key的作用主要是為了高效的更新虛擬DOM。
25.什么是vue的計(jì)算屬性?
答:在模板中放入太多的邏輯會(huì)讓模板過重且難以維護(hù),在需要對數(shù)據(jù)進(jìn)行復(fù)雜處理,且可能多次使用的情況下,盡量采取計(jì)算屬性的方式。好處:①使得數(shù)據(jù)處理結(jié)構(gòu)清晰;②依賴于數(shù)據(jù),數(shù)據(jù)更新,處理結(jié)果自動(dòng)更新;③計(jì)算屬性內(nèi)部this指向vm實(shí)例;④在template調(diào)用時(shí),直接寫計(jì)算屬性名即可;⑤常用的是getter方法,獲取數(shù)據(jù),也可以使用set方法改變數(shù)據(jù);⑥相較于methods,不管依賴的數(shù)據(jù)變不變,methods都會(huì)重新計(jì)算,但是依賴數(shù)據(jù)不變的時(shí)候computed從緩存中獲取,不會(huì)重新計(jì)算。
26.怎么定義 vue-router 的動(dòng)態(tài)路由? 怎么獲取傳過來的值
答:在 router 目錄下的 index.js 文件中,對 path 屬性加上 /:id,使用 router 對象的 params.id 獲取。
27.vue優(yōu)點(diǎn)?
答:輕量級框架:只關(guān)注視圖層,是一個(gè)構(gòu)建數(shù)據(jù)的視圖集合,大小只有幾十kb;
簡單易學(xué):國人開發(fā),中文文檔,不存在語言障礙 ,易于理解和學(xué)習(xí);
雙向數(shù)據(jù)綁定:保留了angular的特點(diǎn),在數(shù)據(jù)操作方面更為簡單;
組件化:保留了react的優(yōu)點(diǎn),實(shí)現(xiàn)了html的封裝和重用,在構(gòu)建單頁面應(yīng)用方面有著獨(dú)特的優(yōu)勢;
視圖,數(shù)據(jù),結(jié)構(gòu)分離:使數(shù)據(jù)的更改更為簡單,不需要進(jìn)行邏輯代碼的修改,只需要操作數(shù)據(jù)就能完成相關(guān)操作;
虛擬DOM:dom操作是非常耗費(fèi)性能的, 不再使用原生的dom操作節(jié)點(diǎn),極大解放dom操作,但具體操作的還是dom不過是換了另一種方式;
運(yùn)行速度更快:相比較與react而言,同樣是操作虛擬dom,就性能而言,vue存在很大的優(yōu)勢。
28.如何獲取dom?
答:ref="domName" 用法:this.$refs.domName
29. vue-loader是什么?使用它的用途有哪些?
答:vue文件的一個(gè)加載器,將template/js/style轉(zhuǎn)換成js模塊。
用途:js可以寫es6、style樣式可以scss或less、template可以加jade等
30.axios及安裝?
答:請求后臺資源的模塊。npm install axios --save裝好,
js中使用import進(jìn)來,然后.get或.post。返回在.then函數(shù)中如果成功,失敗則是在.catch函數(shù)中。
31.請說出vue.cli項(xiàng)目中src目錄每個(gè)文件夾和文件的用法?
答:assets文件夾是放靜態(tài)資源;components是放組件;router是定義路由相關(guān)的配置; app.vue是一個(gè)應(yīng)用主組件;main.js是入口文件。
32.$nextTick的使用
答:當(dāng)你修改了data的值然后馬上獲取這個(gè)dom元素的值,是不能獲取到更新后的值,
你需要使用$nextTick這個(gè)回調(diào),讓修改后的data值渲染更新到dom元素之后在獲取,才能成功。
33.assets和static的區(qū)別
答:相同點(diǎn):assets和static兩個(gè)都是存放靜態(tài)資源文件。項(xiàng)目中所需要的資源文件圖片,字體圖標(biāo),樣式文件等都可以放在這兩個(gè)文件下,這是相同點(diǎn)
不相同點(diǎn):assets中存放的靜態(tài)資源文件在項(xiàng)目打包時(shí),也就是運(yùn)行npm run build時(shí)會(huì)將assets中放置的靜態(tài)資源文件進(jìn)行打包上傳,所謂打包簡單點(diǎn)可以理解為壓縮體積,代碼格式化。而壓縮后的靜態(tài)資源文件最終也都會(huì)放置在static文件中跟著index.html一同上傳至服務(wù)器。static中放置的靜態(tài)資源文件就不會(huì)要走打包壓縮格式化等流程,而是直接進(jìn)入打包好的目錄,直接上傳至服務(wù)器。因?yàn)楸苊饬藟嚎s直接進(jìn)行上傳,在打包時(shí)會(huì)提高一定的效率,但是static中的資源文件由于沒有進(jìn)行壓縮等操作,所以文件的體積也就相對于assets中打包后的文件提交較大點(diǎn)。在服務(wù)器中就會(huì)占據(jù)更大的空間。
建議:將項(xiàng)目中template需要的樣式文件js文件等都可以放置在assets中,走打包這一流程。減少體積。而項(xiàng)目中引入的第三方的資源文件如iconfoont.css等文件可以放置在static中,因?yàn)檫@些引入的第三方文件已經(jīng)經(jīng)過處理,我們不再需要處理,直接上傳。
34.vue和jQuery的區(qū)別
答:jQuery是使用選擇器($)選取DOM對象,對其進(jìn)行賦值、取值、事件綁定等操作,其實(shí)和原生的HTML的區(qū)別只在于可以更方便的選取和操作DOM對象,而數(shù)據(jù)和界面是在一起的。比如需要獲取label標(biāo)簽的內(nèi)容:$("lable").val();,它還是依賴DOM元素的值。
Vue則是通過Vue對象將數(shù)據(jù)和View完全分離開來了。對數(shù)據(jù)進(jìn)行操作不再需要引用相應(yīng)的DOM對象,可以說數(shù)據(jù)和View是分離的,他們通過Vue對象這個(gè)vm實(shí)現(xiàn)相互的綁定。這就是傳說中的MVVM。
35. 引進(jìn)組件的步驟
答: 在template中引入組件;
在script的第一行用import引入路徑;
用component中寫上組件名稱。
36.Vue-router跳轉(zhuǎn)和location.href有什么區(qū)別
答:使用location.href='/url'來跳轉(zhuǎn),簡單方便,但是刷新了頁面;
使用history.pushState('/url'),無刷新頁面,靜態(tài)跳轉(zhuǎn);
引進(jìn)router,然后使用router.push('/url')來跳轉(zhuǎn),使用了diff算法,實(shí)現(xiàn)了按需加載,減少了dom的消耗。
其實(shí)使用router跳轉(zhuǎn)和使用history.pushState()沒什么差別的,因?yàn)関ue-router就是用了history.pushState(),尤其是在history模式下。
37. vue slot
答:簡單來說,假如父組件需要在子組件內(nèi)放一些DOM,那么這些DOM是顯示、不顯示、在哪個(gè)地方顯示、如何顯示,就是slot分發(fā)負(fù)責(zé)的活。
38.axios的特點(diǎn)有哪些
答:從瀏覽器中創(chuàng)建XMLHttpRequests;
node.js創(chuàng)建http請求;
支持Promise API;
攔截請求和響應(yīng);
轉(zhuǎn)換請求數(shù)據(jù)和響應(yīng)數(shù)據(jù);
取消請求;
自動(dòng)換成json。
axios中的發(fā)送字段的參數(shù)是data跟params兩個(gè),兩者的區(qū)別在于params是跟請求地址一起發(fā)送的,data的作為一個(gè)請求體進(jìn)行發(fā)送
params一般適用于get請求,data一般適用于post put 請求。
39.你們vue項(xiàng)目是打包了一個(gè)js文件,一個(gè)css文件,還是有多個(gè)文件?
答:根據(jù)vue-cli腳手架規(guī)范,一個(gè)js文件,一個(gè)CSS文件。
40.Vue里面router-link在電腦上有用,在安卓上沒反應(yīng)怎么解決?
答:Vue路由在Android機(jī)上有問題,babel問題,安裝babel polypill插件解決
41.Vue2中注冊在router-link上事件無效解決方法
答: 使用@click.native。原因:router-link會(huì)阻止click事件,.native指直接監(jiān)聽一個(gè)原生事件。
42.params和query的區(qū)別
答:用法:query要用path來引入,params要用name來引入,接收參數(shù)都是類似的,分別是this.$route.query.name和this.$route.params.name。
url地址顯示:query更加類似于我們ajax中g(shù)et傳參,params則類似于post,說的再簡單一點(diǎn),前者在瀏覽器地址欄中顯示參數(shù),后者則不顯示
注意點(diǎn):query刷新不會(huì)丟失query里面的數(shù)據(jù)
params刷新 會(huì) 丟失 params里面的數(shù)據(jù)。
43.vue初始化頁面閃動(dòng)問題
答:使用vue開發(fā)時(shí),在vue初始化之前,由于div是不歸vue管的,所以我們寫的代碼在還沒有解析的情況下會(huì)容易出現(xiàn)花屏現(xiàn)象,看到類似于{{message}}的字樣,雖然一般情況下這個(gè)時(shí)間很短暫,但是我們還是有必要讓解決這個(gè)問題的。
首先:在css里加上[v-cloak] {
display: none;
}。
如果沒有徹底解決問題,則在根元素加上style="display: none;" :style="{display: 'block'}"
44.vue更新數(shù)組時(shí)觸發(fā)視圖更新的方法
答:push();pop();shift();unshift();splice(); sort();reverse()
45.watch和computed的區(qū)別以及使用場景?
區(qū)別:
watch中的函數(shù)是不需要調(diào)用的
computed內(nèi)部的函數(shù)調(diào)用的時(shí)候不需要加()
watch 屬性監(jiān)聽 監(jiān)聽屬性的變化
computed:計(jì)算屬性 通過屬性計(jì)算而得來的屬性
watch需要在數(shù)據(jù)變化時(shí)執(zhí)行異步或開銷較大的操作時(shí)使用
computed 屬性的結(jié)果會(huì)被緩存,除非依賴的響應(yīng)式屬性變化才會(huì)重新計(jì)算。
主要當(dāng)作屬性來使用。
使用場景:
computed
當(dāng)一個(gè)屬性受多個(gè)屬性影響的時(shí)候就需要用到computed
最典型的例子: 購物車商品結(jié)算的時(shí)候
watch
當(dāng)一條數(shù)據(jù)影響多條數(shù)據(jù)的時(shí)候就需要用watch
搜索數(shù)據(jù)
46 導(dǎo)航守衛(wèi)
1.全局守衛(wèi)
全局前置守衛(wèi)
router.beforeEach((to, from, next) => {
// ...
})
全局后置守衛(wèi)
router.afterEach((to, from) => {
// ...
})
2.路由獨(dú)享守衛(wèi)
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
3.組件內(nèi)的守衛(wèi)
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
// 不!能!獲取組件實(shí)例 `this`
// 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建
},
beforeRouteUpdate (to, from, next) {
// 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
// 舉例來說,對于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候,
// 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。
// 可以訪問組件實(shí)例 `this`
},
beforeRouteLeave (to, from, next) {
// 導(dǎo)航離開該組件的對應(yīng)路由時(shí)調(diào)用
// 可以訪問組件實(shí)例 `this`
}
}
47 路由滾動(dòng)行為
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滾動(dòng)到哪個(gè)的位置
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
})
48.axios是什么?怎么使用?
答案: 請求后臺資源的模塊
使用npm install axios -s 來安裝
在main.js入口文件中引用:import axios from {axios}
將axios掛載到vue實(shí)例上:vue.prototype.$axios = axios
在config文件夾中的index.js中的Dev中填寫
ProxyTable:{
‘/api’:{
Target:’代理服務(wù)器的目標(biāo)地址’,
changeOrigin: true,
PathRewrite: {“^/api”:” ”}
}
}
在需要調(diào)用后臺資源的組件中進(jìn)行使用this.$axios({
Url: ‘/api/地址’,
Method:’post’,//post請求必須設(shè)置
Params:{要傳的參數(shù)}//post要將params設(shè)置為data
}).then(res=>{}).catch(err=>{})
49.如何解決跨域問題
答案:在config文件夾中的index.js中的Dev中填寫
ProxyTable:{
‘/api’:{
Target:’代理服務(wù)器的目標(biāo)地址’,
changeOrigin: true,
PathRewrite: {“^/api”:” ”}
}
}
50.axios面試題
1、axios的特點(diǎn)有哪些?
答:
一、Axios 是一個(gè)基于 promise 的 HTTP 庫,支持promise所有的API
二、它可以攔截請求和響應(yīng)
三、它可以轉(zhuǎn)換請求數(shù)據(jù)和響應(yīng)數(shù)據(jù),并對響應(yīng)回來的內(nèi)容自動(dòng)轉(zhuǎn)換成 JSON類型的數(shù)據(jù)
四、安全性更高,客戶端支持防御 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相關(guān)配置屬性?
答:
`url`是用于請求的服務(wù)器URL
`method`是創(chuàng)建請求時(shí)使用的方法,默認(rèn)是get
`baseURL`將自動(dòng)加在`url`前面,除非`url`是一個(gè)絕對URL。它可以通過設(shè)置一個(gè)`baseURL`便于為axios實(shí)例的方法傳遞相對URL
`transformRequest`允許在向服務(wù)器發(fā)送前,修改請求數(shù)據(jù),只能用在'PUT','POST'和'PATCH'這幾個(gè)請求方法
`headers`是即將被發(fā)送的自定義請求頭
headers:{'X-Requested-With':'XMLHttpRequest'},
`params`是即將與請求一起發(fā)送的URL參數(shù),必須是一個(gè)無格式對象(plainobject)或URLSearchParams對象
params:{
ID:12345
},
`auth`表示應(yīng)該使用HTTP基礎(chǔ)驗(yàn)證,并提供憑據(jù)
這將設(shè)置一個(gè)`Authorization`頭,覆寫掉現(xiàn)有的任意使用`headers`設(shè)置的自定義`Authorization`頭
auth:{
username:'janedoe',
password:'s00pers3cret'
},
'proxy'定義代理服務(wù)器的主機(jī)名稱和端口
`auth`表示HTTP基礎(chǔ)驗(yàn)證應(yīng)當(dāng)用于連接代理,并提供憑據(jù)
這將會(huì)設(shè)置一個(gè)`Proxy-Authorization`頭,覆寫掉已有的通過使用`header`設(shè)置的自定義`Proxy-Authorization`頭。
proxy:{
host:'127.0.0.1',
port:9000,
auth::{
username:'mikeymike',
password:'rapunz3l'
}
},
4、請求攔截器
請求攔截器的作用是在請求發(fā)送前進(jìn)行一些操作,例如在每個(gè)請求體里加上token,統(tǒng)一做了處理如果以后要改也非常容易。
axios.interceptors.request.use(function (config) {
// 在發(fā)送請求之前做些什么,例如加入token
.......
return config;
}, function (error) {
// 對請求錯(cuò)誤做些什么
return Promise.reject(error);
});
5、響應(yīng)攔截器
響應(yīng)攔截器的作用是在接收到響應(yīng)后進(jìn)行一些操作,例如在服務(wù)器返回登錄狀態(tài)失效,需要重新登錄的時(shí)候,跳轉(zhuǎn)到登錄頁
axios.interceptors.response.use(function (response) {
// 在接收響應(yīng)做些什么,例如跳轉(zhuǎn)到登錄頁
......
return response;
}, function (error) {
// 對響應(yīng)錯(cuò)誤做點(diǎn)什么
return Promise.reject(error);
});
總結(jié)
以上是生活随笔為你收集整理的iframe vue 前进 后退_vue常见面试题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: this表示当前对象简单实例
- 下一篇: Lab 6-4