• 原型 構造函數 ,是一種特殊的方法。主要用來在創建對象時初始化對象。每個構造函數都有prototype(原型)屬性 每個函數都有prototype(原型)屬性,這個屬性是一個指針,指向一個對象, 這個對象的用途是包含特定類型的所有實例共享的屬性和方法,即這個原型對象是用來給實例共享屬性和方法的。 而每個實例內部都有一個指向原型對象的指針。 • 閉包 簡單來說就是函數嵌套函數,內部函數引用來外部函數的變量,從而導致來垃圾回收機制沒有生效,變量被保存來下來。 也就是所謂的內存泄漏,然后由於內存泄漏又會導致你項目逐漸變得卡頓等等問題。因此要避免內存泄漏。 • 原型鏈 提到原型鏈就不得不提原型的繼承,繼承的完美實現方案是借助寄生組合繼承,主要實現原理 PersonB.prototype = Object.create(PersonA.prototype)實現來繼承PersonA的原型 當我們通過new關鍵字實例化的對象身上就有了PersonB自身的屬性和方法,也有了PersonA的原型方法 當實例化對象調用某個方法時會先在自身和原型上查找,然后是在_proto_上一層層查找,這種方式就是原型鏈。 • vuex Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態 並以相應的規則保證狀態以一種可預測的方式發生變化。 state:Vuex 使用單一狀態樹——是的,用一個對象就包含了全部的應用層級狀態。 mutation:更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation action: action 提交的是 mutation,而不是直接變更狀態。action 可以包含任意異步操作。 getter: 相當於Vue中的computed計算屬性 • vue-router Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,讓構建單頁面應用變得易如反掌 和和 • 深拷貝淺拷貝 深拷貝: 通過利用JSON.parse(JSON.stringify(Object))來達到深拷貝的目的 但是JSON深拷貝的缺點是undefined和function還有symbol類型是無法進行深拷貝的 如有需要可以自己手動封裝函數來達到目的 淺拷貝: 通過ES6新特性Object.assign()與擴展運算符來達到淺拷貝的目的 • Vue通信 第一種:props和e m i t 第 二 種 : 中 央 事 件 總 線 E v e n t B u s ( 基 本 不 用 ) 第 三 種 : v u e x ( 狀 態 管 理 器 ) 第 四 種 : emit 第二種:中央事件總線 EventBus(基本不用) 第三種:vuex(狀態管理器) 第四種:emit第二種:中央事件總線EventBus(基本不用)第三種:vuex(狀態管理器)第四種:parent 和 $children 當然還有其他辦法,但是基本不常用 • 你在工作終於到那些問題,解決方法是什么 經常遇到的問題就是Cannot read property ‘prototype’ of undefined 解決辦法通過瀏覽器報錯提示代碼定位問題,解決問題 Vue項目中遇到視圖不更新,方法不執行,埋點不觸發等問題 一般解決方案查看瀏覽器報錯,查看代碼運行到那個階段未之行結束,閱讀源碼以及相關文檔等 然后舉出來最近開發的項目中遇到的算是兩個比較大的問題。 • webpack配置入口出口 module.exports={undefined //入口文件的配置項 entry:{}, //出口文件的配置項 output:{}, //模塊:例如解讀CSS,圖片如何轉換,壓縮 module:{}, //插件,用於生產模版和各項功能 plugins:[], //配置webpack開發服務功能 devServer:{} } 簡單描述了一下這幾個屬性是干什么的。 • webpack3和webpack4區別 1.mode webpack增加了一個mode配置,只有兩種值development | production。對不同的環境他會啟用不同的配置。 2.CommonsChunkPlugin CommonChunksPlugin已經從webpack4中移除。 可使用optimization.splitChunks進行模塊划分(提取公用代碼)。 但是需要注意一個問題,默認配置只會對異步請求的模塊進行提取拆分,如果要對entry進行拆分 需要設置optimization.splitChunks.chunks = ‘all’。 3.webpack4使用MiniCssExtractPlugin取代ExtractTextWebpackPlugin。 4.代碼分割。 使用動態import,而不是用system.import或者require.ensure 5.vue-loader。 使用vue-loader插件為.vue文件中的各部分使用相對應的loader,比如css-loader等 6.UglifyJsPlugin 現在也不需要使用這個plugin了,只需要使用optimization.minimize為true就行,production mode下面自動為true optimization.minimizer可以配置你自己的壓縮程序 二面 • 陳述輸入URL回車后的過程 1.讀取緩存: 搜索自身的 DNS 緩存。(如果 DNS 緩存中找到IP 地址就跳過了接下來查找 IP 地址步驟,直接訪問該 IP 地址。) 2.DNS 解析:將域名解析成 IP 地址 3.TCP 連接:TCP 三次握手,簡易描述三次握手 客戶端:服務端你在么? 服務端:客戶端我在,你要連接我么? 客戶端:是的服務端,我要鏈接。 連接打通,可以開始請求來 4.發送 HTTP 請求 5.服務器處理請求並返回 HTTP 報文 6.瀏覽器解析渲染頁面 7.斷開連接:TCP 四次揮手 關於第六步瀏覽器解析渲染頁面又可以聊聊如果返回的是html頁面 根據 HTML 解析出 DOM 樹 根據 CSS 解析生成 CSS 規則樹 結合 DOM 樹和 CSS 規則樹,生成渲染樹 根據渲染樹計算每一個節點的信息 根據計算好的信息繪制頁面 • 陳述http 基本概念: HTTP,全稱為 HyperText Transfer Protocol,即為超文本傳輸協議。是互聯網應用最為廣泛的一種網絡協議 所有的 www 文件都必須遵守這個標准。 http特性: HTTP 是無連接無狀態的 HTTP 一般構建於 TCP/IP 協議之上,默認端口號是 80 HTTP 可以分為兩個部分,即請求和響應。 http請求: HTTP 定義了在與服務器交互的不同方式,最常用的方法有 4 種 分別是 GET,POST,PUT, DELETE。URL 全稱為資源描述符,可以這么認為:一個 URL 地址 對應着一個網絡上的資源,而 HTTP 中的 GET,POST,PUT,DELETE 就對應着對這個資源的查詢,修改,增添,刪除4個操作。 HTTP 請求由 3 個部分構成,分別是:狀態行,請求頭(Request Header),請求正文。 HTTP 響應由 3 個部分構成,分別是:狀態行,響應頭(Response Header),響應正文。 HTTP 響應中包含一個狀態碼,用來表示服務器對客戶端響應的結果。 狀態碼一般由3位構成: 1xx : 表示請求已經接受了,繼續處理。 2xx : 表示請求已經處理掉了。 3xx : 重定向。 4xx : 一般表示客戶請求無端有錯誤,法實現。 5xx : 一般為服務器端的錯誤。 比如常見的狀態碼: 200 OK 客戶端請求成功。 301 Moved Permanently 請求永久重定向。 302 Moved Temporarily 請求臨時重定向。 304 Not Modified 文件未修改,可以直接使用緩存的文件。 400 Bad Request 由於客戶端請求有語法錯誤,不能被服務器所理解。 401 Unauthorized 請求未經授權,無法訪問。 403 Forbidden 服務器收到請求,但是拒絕提供服務。服務器通常會在響應正文中給出不提供服務的原因。 404 Not Found 請求的資源不存在,比如輸入了錯誤的URL。 500 Internal Server Error 服務器發生不可預期的錯誤,導致無法完成客戶端的請求。 503 Service Unavailable 服務器當前不能夠處理客戶端的請求,在一段時間之后,服務器可能會恢復正常。 大概還有一些關於hhtp請求和響應頭信息的介紹。 • 說說Vue原理 Vue是采用數據劫持配合發布者-訂閱者模式,通過Object.defineProperty來()來劫持各個屬性的getter和setter 在數據發生變化的時候,發布消息給依賴收集器,去通知觀察者,做出對應的回調函數去更新視圖。 具體就是: MVVM作為綁定的入口,整合Observe,Compil和Watcher三者,通過Observe來監聽model的變化 通過Compil來解析編譯模版指令,最終利用Watcher搭起Observe和Compil之前的通信橋梁 從而達到數據變化 => 更新視圖,視圖交互變化(input) => 數據model變更的雙向綁定效果。 • Vue路由守衛有哪些,怎么設置,使用場景等 常用的兩個路由守衛:router.beforeEach 和 router.afterEach 每個守衛方法接收三個參數: to: Route: 即將要進入的目標 路由對象 from: Route: 當前導航正要離開的路由 next: Function: 一定要調用該方法來 resolve 這個鈎子。 在項目中,一般在beforeEach這個鈎子函數中進行路由跳轉的一些信息判斷。 判斷是否登錄,是否拿到對應的路由權限等等。 • 數組去重 第一種:通過ES6新特性Set() 例如:var arr = [1, 2, 3, 1, 2]; var newArr= […new Set(arr)] 第二種:封裝函數利用 {} 和【】 function uniqueEasy(arr) {undefined if(!arr instanceof Array) {undefined throw Error(‘當前傳入的不是數組’) } let list = [] let obj = {} arr.forEach(item => {undefined if(!obj[item]) {undefined list.push(item) obj[item] = true } }) return list } 當然還有其他的方法,但本人項目中一般使用以上兩種基本滿足 • Set,Map解構 ES6 提供了新的數據結構 Set。 它類似於數組,但是成員的值都是唯一的,沒有重復的值。Set 本身是一個構造函數,用來生成 Set 數據結構。 ES6 提供了 Map 數據結構。它類似於對象,也是鍵值對的集合,但是“鍵”的范圍不限於字符串,各種類型的值(包括對象)都可以當作鍵。 • 對數組排序 第一種方法利用sort方法 第二種利用冒泡排序 • 說一說js是什么語言 js是一種運行在瀏覽器的腳本語言,這種語言主要的功能是可以制作出動態的頁面的效果 我們可以通過js+css+html布局來形成我們現在可以訪問展示的頁面 js語言是弱語言類型, 因此我們在項目開發中當我們隨意更該某個變量的數據類型后 有可能會導致其他引用這個變量的方法中報錯等等。 • 原型 JavaScript中的對象都有一個特殊的 prototype 內置屬性,其實就是對其他對象的引用 幾乎所有的對象在創建時 prototype 屬性都會被賦予一個非空的值,我們可以把這個屬性當作一個備用的倉庫 當試圖引用對象的屬性時會出發get操作,第一步時檢查對象本身是否有這個屬性,如果有就使用它,沒有就去原型中查找。一層層向上直到Object.prototype頂層 基於原型擴展描述一下原型鏈,什么是原型鏈,原型的繼承,ES5和ES6繼承與不同點。 • ES6新特性 1.ES6引入來嚴格模式 變量必須聲明后在使用 函數的參數不能有同名屬性, 否則報錯 不能使用with語句 (說實話我基本沒用過) 不能對只讀屬性賦值, 否則報錯 不能使用前綴0表示八進制數,否則報錯 (說實話我基本沒用過) 不能刪除不可刪除的數據, 否則報錯 不能刪除變量delete prop, 會報錯, 只能刪除屬性delete global[prop] eval不會在它的外層作用域引入變量 eval和arguments不能被重新賦值 arguments不會自動反映函數參數的變化 不能使用arguments.caller (說實話我基本沒用過) 不能使用arguments.callee (說實話我基本沒用過) 禁止this指向全局對象 不能使用fn.caller和fn.arguments獲取函數調用的堆棧 (說實話我基本沒用過) 增加了保留字(比如protected、static和interface) 2.關於let和const新增的變量聲明 3.變量的解構賦值 4.字符串的擴展 includes():返回布爾值,表示是否找到了參數字符串。 startsWith():返回布爾值,表示參數字符串是否在原字符串的頭部。 endsWith():返回布爾值,表示參數字符串是否在原字符串的尾部。 5.數值的擴展 Number.isFinite()用來檢查一個數值是否為有限的(finite)。 Number.isNaN()用來檢查一個值是否為NaN。 6.函數的擴展 函數參數指定默認值 7.數組的擴展 擴展運算符 8.對象的擴展 對象的解構 9.新增symbol數據類型 10.Set 和 Map 數據結構 ES6 提供了新的數據結構 Set。它類似於數組,但是成員的值都是唯一的,沒有重復的值。Set 本身是一個構造函數,用來生成 Set 數據結構。 Map它類似於對象,也是鍵值對的集合,但是“鍵”的范圍不限於字符串,各種類型的值(包括對象)都可以當作鍵。 1 11.Proxy Proxy 可以理解成,在目標對象之前架設一層“攔截”,外界對該對象的訪問 都必須先通過這層攔截,因此提供了一種機制,可以對外界的訪問進行過濾和改寫。 Proxy 這個詞的原意是代理,用在這里表示由它來“代理”某些操作,可以譯為“代理器”。 Vue3.0使用了proxy 12.Promise Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。 特點是: 對象的狀態不受外界影響。 一旦狀態改變,就不會再變,任何時候都可以得到這個結果。 13.async 函數 async函數對 Generator 函數的區別: (1)內置執行器。 Generator 函數的執行必須靠執行器,而async函數自帶執行器。也就是說,async函數的執行,與普通函數一模一樣,只要一行。 (2)更好的語義。 async和await,比起星號和yield,語義更清楚了。async表示函數里有異步操作,await表示緊跟在后面的表達式需要等待結果。 (3)正常情況下,await命令后面是一個 Promise 對象。如果不是,會被轉成一個立即resolve的 Promise 對象。 (4)返回值是 Promise。 async函數的返回值是 Promise 對象,這比 Generator 函數的返回值是 Iterator 對象方便多了。你可以用then方法指定下一步的操作。 14.Class class跟let、const一樣:不存在變量提升、不能重復聲明… ES6 的class可以看作只是一個語法糖,它的絕大部分功能 ES5 都可以做到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。 15.Module ES6 的模塊自動采用嚴格模式,不管你有沒有在模塊頭部加上"use strict";。 import和export命令以及export和export default的區別 • Css3新特性 1.過渡 transition 2.動畫 animation 3.形狀轉換 transform 4.陰影 box-shadow 5.濾鏡 Filter 6.顏色 rgba 7.柵格布局 gird 8.彈性布局 flex 等等還多… • 說一說你用過的UI框架 Element-UI Vant • 說一說什么是跨域,怎么解決 因為瀏覽器出於安全考慮,有同源策略。也就是說,如果協議、域名或者端口有一個不同就是跨域,Ajax 請求會失敗。 為來防止CSRF攻擊 1.JSONP JSONP 的原理很簡單,就是利用 JSONP 使用簡單且兼容性不錯,但是只限於 get 請求。 2.CORS CORS 需要瀏覽器和后端同時支持。IE 8 和 9 需要通過 XDomainRequest 來實現。 3.document.domain 該方式只能用於二級域名相同的情況下,比如 a.test.com 和 b.test.com 適用於該方式。 只需要給頁面添加 document.domain = 'test.com' 表示二級域名都相同就可以實現跨域 1 4.webpack配置proxyTable設置開發環境跨域 5.nginx代理跨域 6.iframe跨域 7.postMessage 這種方式通常用於獲取嵌入頁面中的第三方頁面數據。一個頁面發送消息,另一個頁面判斷來源並接收消息 • 說一說前端性能優化方案 三個方面來說明前端性能優化 一:webapck優化與開啟gzip壓縮 1.babel-loader用 include 或 exclude 來幫我們避免不必要的轉譯,不轉譯node_moudules中的js文件 其次在緩存當前轉譯的js文件,設置loader: ‘babel-loader?cacheDirectory=true’ 2.文件采用按需加載等等 3.具體的做法非常簡單,只需要你在你的 request headers 中加上這么一句: accept-encoding:gzip 4.圖片優化,采用svg圖片或者字體圖標 5.瀏覽器緩存機制,它又分為強緩存和協商緩存 二:本地存儲——從 Cookie 到 Web Storage、IndexedDB 說明一下SessionStorage和localStorage還有cookie的區別和優缺點 三:代碼優化 1.事件代理 2.事件的節流和防抖 3.頁面的回流和重繪 4.EventLoop事件循環機制 5.代碼優化等等 • 說一說SessionStorage和localStorage還有cookie 共同點:都是保存在瀏覽器端、且同源的 不同點: 1.cookie數據始終在同源的http請求中攜帶(即使不需要),即cookie在瀏覽器和服務器間來回傳遞。 cookie數據還有路徑(path)的概念,可以限制cookie只屬於某個路徑下 sessionStorage和localStorage不會自動把數據發送給服務器,僅在本地保存。 2.存儲大小限制也不同,cookie數據不能超過4K,sessionStorage和localStorage可以達到5M 3.sessionStorage:僅在當前瀏覽器窗口關閉之前有效; localStorage:始終有效,窗口或瀏覽器關閉也一直保存,本地存儲,因此用作持久數據; cookie:只在設置的cookie過期時間之前有效,即使窗口關閉或瀏覽器關閉 4.作用域不同 sessionStorage:不在不同的瀏覽器窗口中共享,即使是同一個頁面; localstorage:在所有同源窗口中都是共享的;也就是說只要瀏覽器不關閉,數據仍然存在 cookie: 也是在所有同源窗口中都是共享的.也就是說只要瀏覽器不關閉,數據仍然存在 • 說一說你用過的css布局 gird布局,layout布局,flex布局,雙飛翼,聖杯布局等 • Promise是什么,解決了什么,之前怎么實現的 Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。 解決來之前在請求中回調請求產生的回調地獄,使得現在的代碼更加合理更加優雅,也更加容易定位查找問題。 • 說說瀏覽器緩存 緩存可以減少網絡 IO 消耗,提高訪問速度。瀏覽器緩存是一種操作簡單、效果顯著的前端性能優化手段 很多時候,大家傾向於將瀏覽器緩存簡單地理解為“HTTP 緩存”。 但事實上,瀏覽器緩存機制有四個方面,它們按照獲取資源時請求的優先級依次排列如下: Memory Cache Service Worker Cache HTTP Cache Push Cache 緩存它又分為強緩存和協商緩存。優先級較高的是強緩存,在命中強緩存失敗的情況下,才會走協商緩存 實現強緩存,過去我們一直用 expires。 當服務器返回響應時,在 Response Headers 中將過期時間寫入 expires 字段,現在一般使用Cache-Control 兩者同時出現使用Cache-Control 協商緩存,Last-Modified 是一個時間戳,如果我們啟用了協商緩存,它會在首次請求時隨着 Response Headers 返回:每次請求去判斷這個時間戳是否發生變化。 從而去決定你是304讀取緩存還是給你返回最新的數據 1 2 使用Vuex只需執行 Vue.use(Vuex),並在Vue的配置中傳入一個store對象的示例,store是如何實現注入的?state內部是如何實現支持模塊配置和模塊嵌套的?在執行dispatch觸發action(commit同理)的時候,只需傳入(type, payload),action執行函數中第一個參數store從哪里獲取的?如何區分state是外部直接修改,還是通過mutation方法修改的?帶着這些疑問,讓我們先從什么是vuex開始—— 一、vuex是什么? Vuex是專門為Vue服務,用於管理頁面的數據狀態、提供統一數據操作的狀態管理系統,相當於數據庫mongoDB,MySQL等,只不過它的數據是存儲在內存中,頁面刷新即消失。 二、vue和vuex關系 看一下這個vue響應式的例子,vue中的data 、methods、computed,可以實現響應式。視圖通過點擊事件,觸發methods中的increment方法,可以更改state中count的值,一旦count值發生變化,computed中的函數能夠把getCount更新到視圖。 那么vuex又和vue這個響應式的例子有什么關系呢?視圖通過點擊事件,觸發mutations中方法,可以更改state中的數據,一旦state數據發生更改,getters把數據反映到視圖。那么actions,可以理解處理異步,而單純多加的一層。既然提到了mutions actions這時候 就不得不提commit,dispatch這兩個有什么作用呢?在vue例子中,通過click事件,觸發methods中的方法。當存在異步時,而在vuex中需要dispatch來觸發actions中的方法,actions中的commit可以觸發mutations中的方法。同步,則直接在組件中commit觸發vuex中mutations中的方法。 三、vuex實現 我們看下vuex中能像vue中實現改變狀態,更新視圖的功能 Store/index.js App.vue 四、源碼分析 store注入組件install方法vuex是通過vue插件機制將組件注入的 首先使用vuex,需要安裝插件: 可見,store注入 vue的實例組件的方式,是通過vue的 mixin機制,借助vue組件的生命周期 鈎子 beforeCreate 完成的。即 每個vue組件實例化過程中,會在 beforeCreate 鈎子前調用 vuexInit 方法。 vuex中的數據雙向綁定 getters實現 從上面源碼,我們可以看出Vuex的state狀態是響應式,是借助vue的data是響應式,將state存入vue實例組件的data中;Vuex的getters則是借助vue的計算屬性computed實現數據實時監聽。 mutations實現 actions實現 五、小結 Vuex是通過全局注入store對象,來實現組件間的狀態共享。在大型復雜的項目中(多級組件嵌套),需要實現一個組件更改某個數據,多個組件自動獲取更改后的數據進行業務邏輯處理,這時候使用vuex比較合適。假如只是多個組件間傳遞數據,使用vuex未免有點大材小用,其實只用使用組件間常用的通信方法即可。 前言 最近看到一些人在問單頁面和多頁面應用的區別。所以也就輸出這一篇短文希望可以給你一個整體的認識。 這里也會大體介紹單頁應用實現的核心 —— 前端路由。 單頁應用 VS 多頁應用 對比圖 單頁應用(SinglePage Application,SPA) 指只有一個主頁面的應用,一開始只需加載一次 js,css 等相關資源。所有的內容都包含在主頁面,對每一個功能模塊組件化。單頁應用跳轉,就是切換相關組件,僅刷新局部資源。 多頁應用(MultiPage Application,MPA) 指有多個獨立的頁面的應用,每個頁面必須重復加載 js,css 等相關資源。多頁應用跳轉,需要整頁資源刷新。 兩者對比表格: 單頁應用實現核心:前端路由 前端路由的核心:改變視圖的同時不會向后端發出請求。 這里我講講 vue-router 路由的兩種模式:hash&history 1、hash 模式 hash 模式背后的原理是 onhashchange 事件。 window.addEventListener( hashchange ,function(e) { console.log(e.oldURL); 1 console.log(e.newURL) 1 },false); 通過 window.location.hash 屬性獲取和設置 hash 值。 由於 hash 發生變化的 url 都會被瀏覽器記錄下來,所以瀏覽器的前進后退可以使用,盡管瀏覽器沒有請求服務器,但是頁面狀態和 url 關聯起來。后來人們稱其為前端路由,成為單頁應用標配。 hash 模式的特點在於 hash 出現在 url 中,但是不會被包括在 HTTP 請求中,對后端沒有影響,不會重新加載頁面。 2、history 模式 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState(),它們提供了對歷史記錄進行修改的功能。 相關的 API: history.pushState() history.pushState(stateObj, title, url); state:一個與指定網址相關的狀態對象, popstate 事件觸發時,該對象會傳入回調函數。如果不需要可填 null。 title:新頁面的標題,但是所有瀏覽器目前都忽略這個值,可填 null。 url:新的網址,必須與當前頁面處在同一個域。瀏覽器的地址欄將顯示這個網址。 例如:history.pushState( new , new , new.html ); 添加上面這個新記錄后,瀏覽器地址欄立刻顯示 ~/new.html,但並不會跳轉到 new.html,它只是成為 history 中的最新記錄。pushState 方法不會觸發頁面刷新,只是 history 對象變化,地址欄會變。 history.replaceState() history.replaceState(stateObj, title, url); 參數同 pushState() 一樣。 調用該方法,會修改當前的 history 對象記錄, history.length 的長度不會改變 history.state 當前 URL 下對應的狀態信息。如果當前 URL 不是通過 pushState 或者 replaceState 產生的,那么 history.state是 null。當需要 state 和 URL 同步時可以使用 replaceState() 使之同步。 popstate 事件 同一個文檔的 history 對象出現變化時,就會觸發 popstate 事件。 不同的瀏覽器在加載頁面時處理 popstate 事件的形式存在差異。頁面加載時 Chrome 和 Safari 通常會觸發 popstate 事件,但 Firefox 則不會。 注意:調用 history.pushState() 或者 history.replaceState() 不會觸發 popstate 事件。 popstate 事件只會在瀏覽器某些行為下觸發, 比如點擊后退、前進按鈕(或者調用 history.back()、history.forward()、history.go()方法)。 1、什么是發布/訂閱模式、觀察者模式? 觀察者模式是觀察者和被觀察者之間的通訊,發布/訂閱模式是“一對多”的依賴關系 2、如何理解Vue2響應式原理? (1)利用Object.defineProperty重新定義一遍目標對象,完成對目標對象的劫持,在屬性值變化后即觸發set方法 后通知訂閱者,告訴該對象的某個屬性值發生了變化。 (2)解析器Compile解析模板中的指令,收集指令所依賴的方法和數據,等待數據變化然后進行渲染。 (3)Watcher在收到屬性值發生變化后,根據解析器Compile提供的指令進行視圖渲染。 3、vuex的工作原理是什么? 每一個 Vuex 應用的核心就是 store(倉庫)。“store”基本上就是一個容器,它包含着你的應用中大部分的狀態 (state) 多個視圖依賴於同一狀態。 來自不同視圖的行為需要變更同一狀態。 vuex 類似Redux 的狀態管理器, 用來管理Vue的所有組件狀態 采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。 4、談一談nextTick 的原理以及運行機制? vue用異步隊列的方式來控制DOM更新和nextTick回調先后執行 microtask因為其高優先級特性,能確保隊列中的微任務在一次事件循環前被執行完畢 因為瀏覽器和移動端兼容問題,vue不得不做了microtask向macrotask的兼容(降級)方案 它可以在DOM更新完畢之后執行一個回調,一般來說,在對於MVVM框架結構的技術棧是不推薦操作DOM的,但是很多情況下可能會需要操作DOM,特別是一些charts插件等所以nextTick就出現了,確保我們所操作的DOM是更新之后的 5、聊聊keep-alive 的實現原理和緩存策略 包裹動態組件時,會緩存不活動的組件實例,而不是銷毀它們,是一個抽象組件:它自身不會渲染一個 DOM 元素,也不會出現在父組件鏈中。當組件在 內被切換,它的 activated 和 deactivated 這兩個生命周期鈎子函數將會被對應執行。 獲取 keep-alive 包裹着的第一個子組件對象及其組件名 根據設定的 include/exclude(如果有)進行條件匹配,決定是否緩存。不匹配,直接返回組件實例 根據組件 ID 和 tag 生成緩存 Key,並在緩存對象中查找是否已緩存過該組件實例。如果存在,直接取出緩存值並更新該 key 在 this.keys 中的位置(更新 key 的位置是實現 LRU 置換策略的關鍵) 在 this.cache 對象中存儲該組件實例並保存 key 值,之后檢查緩存的實例數量是否超過 max 的設置值,超過則根據 LRU 置換策略刪除最近最久未使用的實例(即是下標為 0 的那個 key) 最后組件實例的 keepAlive 屬性設置為 true,這個在渲染和執行被包裹組件的鈎子函數會用到, 6、你閱讀過axios的 源碼嗎 ?Axios主要有哪些特性? 1、在瀏覽器中發送 XMLHttpRequests 請求; 2、在 node.js 中發送 http請求; 3、基於 promise 的 HTTP 庫,支持promise所有的API 4、攔截請求和響應;(修改請求數據,只能用在’PUT’,'POST’和’PATCH’這幾個請求方法) 5、轉換請求和響應數據,響應回來的內容自動轉換; 6、自動轉換 JSON 數據; 7、客戶端支持保護安全免受 XSRF 攻擊; 7、Vuex與Redux比較,他們的相同點以及不同點? vuex的同步異步方式不一樣, view——>commit——>mutations——>state變化——>view變化(同步操作) view——>dispatch——>actions——>mutations—>state變化—>view變化(異步操作) redux的同步異步方式一樣。 view—>dispatch—>actions—>reducer——>state變化——>view變化(同步異步一樣) 2.用過redux的知道redux需要增加訂閱函數,也就是我們的 store.subscribe(render),但是vue是雙向綁定,不需要這步操作 3.vuex只能和vue配合,vuex把redux里面的reducer部分改成了mutations,但是reducer里面需要分情況,要么switch,要么if else,但是vuex里面的mutations,里面你直接寫方法就完事了。 4.vuex里面有個module 8、在vue 中 如何 通過createElement創建虛擬dom? 在Vue的底層實現上,Vue將模板編譯成虛擬DOM渲染函數。結合Vue自帶的響應系統,在狀態改變時,Vue能夠智能地計算出重新渲染組件的最小代價並應到DOM操作上。 createElement 默認暴露給用戶傳遞3個參數,{String | Object | Function} ,createElement 最終是通過調用new VNode 來創建虛擬dom,函數在調用new VNode之前處理了很多限制的情況,比如:data不能是響應式數據,tag是否為空等等 9、如何通過vue, vue-router, vuex進行權限控制? https://www.cnblogs.com/zhengrunlin/p/8981017.html 10、vue的數據驅動原理及如何實現? vue實現對數據的雙向綁定,通過對數據劫持結合發布者-訂閱者模式實現的。 https://segmentfault.com/a/1190000013276124