小程序個人開發(fā)全過程天津seo推廣
一、CSS
1.說一下CSS的盒模型。
在HTML頁面中的所有元素都可以看成是一個盒子
盒子的組成:內(nèi)容content、內(nèi)邊距padding、邊框border、外邊距margin
盒模型的類型:
標(biāo)準(zhǔn)盒模型
margin + border + padding + content
IE盒模型
margin + content(border + padding)
控制盒模型的模式:box-sizing:content-box(默認(rèn)值,標(biāo)準(zhǔn)盒模型)、border-box(IE盒模型);
2.CSS選擇器的優(yōu)先級?
CSS的特性:繼承性、層疊性、優(yōu)先級
優(yōu)先級:寫CSS樣式的時候,會給同一個元素添加多個樣式,此時誰的權(quán)重高就顯示誰的樣式
標(biāo)簽、類/偽類/屬性、全局選擇器、行內(nèi)樣式、id、!important
!important > 行內(nèi)樣式 > id > 類/偽類/屬性 > 標(biāo)簽 > 全局選擇器
3.隱藏元素的方法有哪些?
display:none;
元素在頁面上消失,不占據(jù)空間
opacity:0;
設(shè)置了元素的透明度為0,元素不可見,占據(jù)空間位置
visibility:hidden;
讓元素消失,占據(jù)空間位置,一種不可見的狀態(tài)
position:absolute;
clip-path
4.px和rem的區(qū)別是什么?
px是像素,顯示器上給我們呈現(xiàn)畫面的像素,每個像素的大小是一樣,絕對單位長度
rem,相對單位,相對于html根節(jié)點的font-size的值,直接給html節(jié)點的font-size:62.5%;
1rem = 10px; (16px*62.5%=10px)
5.重繪重排有什么區(qū)別?
重排(回流):布局引擎會根據(jù)所有的樣式計算出盒模型在頁面上的位置和大小
重繪:計算好盒模型的位置、大小和其他一些屬性之后,瀏覽器就會根據(jù)每個盒模型的特性進(jìn)行繪制
瀏覽器的渲染機制
對DOM的大小、位置進(jìn)行修改后,瀏覽器需要重新計算元素的這些幾何屬性,就叫重排
對DOM的樣式進(jìn)行修改,比如color和background-color,瀏覽器不需要重新計算幾何屬性的時候,直接繪制了該元素的新樣式,那么這里就只觸發(fā)了重繪
6.讓一個元素水平垂直居中的方式有哪些?
1.定位+margin
2.定位+transform
3.flex布局
4.grid布局
5.table布局
7.CSS的哪些屬性哪些可以繼承?哪些不可以繼承?
CSS的三大特性:繼承、層疊、優(yōu)先級
子元素可以繼承父類元素的樣式
1.字體的一些屬性:font
2.文本的一些屬性:line-height
3.元素的可見性:visibility:hidden
4.表格布局的屬性:border-spacing
5.列表的屬性:list-style
6.頁面樣式屬性:page
7.聲音的樣式屬性
8.有沒有用過預(yù)處理器?
預(yù)處理語言增加了變量、函數(shù)、混入等強大的功能
SASS LESS
?
二、JavaSscipt
1.JS由哪三部分組成?
ECMAScript:JS的核心內(nèi)容,描述了語言的基礎(chǔ)語法,比如var,for,數(shù)據(jù)類型(數(shù)組、字符串),
文檔對象模型(DOM):DOM把整個HTML頁面規(guī)劃為元素構(gòu)成的文檔
瀏覽器對象模型(BOM):對瀏覽器窗口進(jìn)行訪問和操作
2.JS有哪些內(nèi)置對象?
String Boolean Number Array Object Function Math Date RegExp...
Math
abs() sqrt() max() min()
Data
new Data() getYear()
Array
String
concat() length slice() split()
3.操作數(shù)組的方法有哪些?
push() pop() sort() splice() unshift() shift() reverse() concat() join() map() filter()
ervery() some() reduce() isArray() findIndex()
哪些方法會改變原數(shù)組?
push() pop() unshift() shift() sort() reverse() splice()
4.JS對數(shù)據(jù)類的檢測方式有哪些?
typeof()
instanceof()
constructor
Object.prototype.toString.call()
5.說一下閉包,閉包有什么特點?
什么是閉包?函數(shù)嵌套函數(shù),內(nèi)部函數(shù)被外部函數(shù)返回并保存下來時,就會產(chǎn)生閉包
特點:可以重復(fù)利用變量,并且這個變量不會污染全局的一種機制;這個變量是一直保存再內(nèi)存中,不會被垃圾回收機制回收
缺點:閉包較多的時候,會消耗內(nèi)存,導(dǎo)致頁面的性能下降,在IE瀏覽器中才會導(dǎo)致內(nèi)存泄漏
使用場景:防抖,節(jié)流,函數(shù)嵌套函數(shù)避免全局污染的時候
6.前端的內(nèi)存泄漏怎么理解?
JS里已經(jīng)分配內(nèi)存地址的對象,但是由于長時間沒有釋放或者沒辦法清除,造成長期占用內(nèi)存的現(xiàn)象,會讓內(nèi)存資源大幅浪費,最終導(dǎo)致運行速度慢,甚至崩潰的情況。
垃圾回收機制
因素:一些為生命直接賦值的變量;一些未清空的定時器;過度的閉包;一些引用元素沒有被清除。
7.事件委托是什么?
又叫事件代理,原理就是利用了事件冒泡的機制來實現(xiàn),也就是說把子元素的事件綁定到了父元素的身上
如果子元素組織了事件冒泡,那么委托也就不成立
組織事件冒泡:event.stopPropagation()
addEventListener('click',函數(shù)名,true/false) 默認(rèn)是false(事件冒泡),true(事件捕獲)
好處:提高性能,減少事件的綁定,也就減少了內(nèi)存的占用。
8.基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的區(qū)別?
基本數(shù)據(jù)類型:String Number Boolean undefined null
基本數(shù)據(jù)類型保存在棧內(nèi)存當(dāng)中,保存的就是一個具體的值
引用數(shù)據(jù)類型(復(fù)雜數(shù)據(jù)類型):Object Function Array
保存在堆內(nèi)存當(dāng)中,聲明一個引用類型的變量,它保存的是引用類型數(shù)據(jù)的地址
假如聲明兩個引用類型同時指向了一個地址的時候,修改其中一個那么另外一個也會改變
9.說一下原型鏈。
原型就是一個普通對象,它是為構(gòu)造函數(shù)的實例共享屬性和方法;所有實例中引用的原型都是同一個對象
使用prototype可以把方法掛在原型上,內(nèi)存值保存一份
__proto__可以理解為指針,實例對象中的屬性,指向了構(gòu)造函數(shù)的原型(prototype)
10.new操作符具體做了什么?
1.先創(chuàng)建一個空對象
2.把空對象和構(gòu)造函數(shù)通過原型鏈進(jìn)行鏈接
3.把構(gòu)造函數(shù)的this綁定到新的空對象身上
4.根據(jù)構(gòu)建函數(shù)返回的類型判斷,如果是值類型,則返回對象,如果是引用類型,就要返回這個引用類型
11.JS是如何實現(xiàn)繼承的?
1.原型鏈繼承
2.借用構(gòu)造函數(shù)繼承
3.組合式繼承
4.ES6的class類繼承
12.JS的設(shè)計原理是什么?
JS引擎 運行上下文 調(diào)用棧 事件循環(huán) 回調(diào)
13.JS中關(guān)于this指向的問題
1. 全局對象中的this指向
指向的是window
2. 全局作用域或者普通函數(shù)中的this
指向全局window
3. this永遠(yuǎn)指向最后調(diào)用它的那個對象
在不是箭頭函數(shù)的情況下
4. new 關(guān)鍵詞改變了this的指向
5. apply,call,bind
可以改變this指向,不是箭頭函數(shù)
6. 箭頭函數(shù)中的this
它的指向在定義的時候就已經(jīng)確定了
箭頭函數(shù)它沒有this,看外層是否有函數(shù),有就是外層函數(shù)的this,沒有就是window
7. 匿名函數(shù)中的this
永遠(yuǎn)指向了window,匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此this指向window
14.script標(biāo)簽里的async和defer有什么區(qū)別?
當(dāng)沒有async和defer這兩個屬性的時候,
瀏覽器會立刻加載并執(zhí)行指定的腳本
有async
加載和渲染后面元素的過程將和script的加載和執(zhí)行并行進(jìn)行(異步)
有defer
加載和渲染后面元素的過程將和script的加載并行進(jìn)行(異步),但是它的執(zhí)行事件要等
所有元素解析完成之后才會執(zhí)行
15.setTimeout最小執(zhí)行時間是多少?
HTML5規(guī)定的內(nèi)容:
setTimeout最小執(zhí)行時間是4ms
setInterval最小執(zhí)行時間是10ms
16.ES6和ES5有什么區(qū)別?
JS的組成:ECMAScript BOM DOM
ES5:ECMAScript5,2009年ECMAScript的第五次修訂,ECMAScript2009
ES6:ECMAScript6,2015年ECMAScript的第六次修訂,ECMAScript2015,是JS的下一個版本標(biāo)準(zhǔn)
17.ES6的新特性有哪些?
1.新增塊級作用域(let,const)
不存在變量提升
存在暫時性死區(qū)的問題
塊級作用域的內(nèi)容
不能在同一個作用域內(nèi)重復(fù)聲明
2.新增了定義類的語法糖(class)
3.新增了一種基本數(shù)據(jù)類型(symbol)
4.新增了解構(gòu)賦值
從數(shù)組或者對象中取值,然后給變量賦值
5.新增了函數(shù)參數(shù)的默認(rèn)值
6.給數(shù)組新增了API
7.對象和數(shù)組新增了擴展運算符
8.Promise
解決回調(diào)地獄的問題。
自身有all,reject,resolve,race方法
原型上有then,catch
把異步操作隊列化
三種狀態(tài):pending初始狀態(tài),fulfilled操作成功,rejected操作失敗
狀態(tài):pending -> fulfilled;pending -> rejected 一旦發(fā)生,狀態(tài)就會凝固,不會再變
async await
同步代碼做異步的操作,兩者必須搭配使用
async表明函數(shù)內(nèi)有異步操作,調(diào)用函數(shù)會返回promise
await是組成async的表達(dá)式,結(jié)果是取決于它等待的內(nèi)容,如果是promise那就是promise的結(jié)果,如果是普通函數(shù)就進(jìn)行鏈?zhǔn)秸{(diào)用
await后的promise如果是reject狀態(tài),那么整個async函數(shù)都會中斷,后面的代碼不執(zhí)行
9.新增了模塊化(import,export)
10.新增了set和map數(shù)據(jù)結(jié)構(gòu)
set就是不重復(fù)
map的key的類型不受限制
11.新增了generator
12.新增了箭頭函數(shù)
不能作為構(gòu)造函數(shù)使用,不能用new
箭頭函數(shù)就沒有原型
箭頭函數(shù)沒有arguments
箭頭函數(shù)不能用call,apply,bind去改變this的執(zhí)行
this指向外層第一個函數(shù)的this
18.call,aply,bind三者有什么區(qū)別?
都是改變this指向和函數(shù)的調(diào)用,call和apply的功能類似,只是傳參的方法不同
call方法傳的是一個參數(shù)列表
apply傳遞的是一個數(shù)組
bind傳參后不會立刻執(zhí)行,會返回一個改變了this指向的函數(shù),這個函數(shù)還是可以傳參的,bind()()
call方法的性能要比apply好一些,所以call用的更多一點
19.用遞歸的時候有沒有遇到什么問題?
如果一個函數(shù)內(nèi)可以調(diào)用函數(shù)本身,那么這個就是遞歸函數(shù)
函數(shù)內(nèi)部調(diào)用自己
特別注意:寫遞歸必須要有退出條件return
20.如何實現(xiàn)一個深拷貝?
深拷貝就是完全拷貝一份新的對象,會在堆內(nèi)存中開辟新的空間,拷貝的對象被修改后,原對象不受影響
主要針對的是引用數(shù)據(jù)類型
1.擴展運算符
2.JSON.parse(JSON.stringify())
3.利用遞歸函數(shù)實現(xiàn)
21.說一下事件循環(huán)。
JS是一個單線程的腳本語言
主線程 執(zhí)行棧 任務(wù)隊列 宏任務(wù) 微任務(wù)
主線程先執(zhí)行同步任務(wù),然后才去執(zhí)行任務(wù)隊列里的任務(wù),如果在執(zhí)行宏任務(wù)之前有微任務(wù),那么要先執(zhí)行微任務(wù)
全部執(zhí)行完之后等待主線程的調(diào)用,調(diào)用完之后再去任務(wù)隊列中查看是否有異步任務(wù),這樣一個循環(huán)往復(fù)的過程就是事件循環(huán)!
22.ajax是什么?怎么實現(xiàn)的?
創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)
在不重新加載整個網(wǎng)頁的前提下,與服務(wù)器交換數(shù)據(jù)并更新部分內(nèi)容
通過XmlHttpRequest對象向服務(wù)器發(fā)送異步請求,然后從服務(wù)器拿到數(shù)據(jù),最后通過JS操作DOM更新頁面
1.創(chuàng)建XmlHttpRequest對象 xmh
2.通過xmh對象里的open()方法和服務(wù)器建立連接
3.構(gòu)建請求所需的數(shù)據(jù),并通過xmh對象的send()發(fā)送給服務(wù)器
4.通過xmh對象的onreadystate chansge事件監(jiān)聽服務(wù)器和你的通信狀態(tài)
5.接收并處理服務(wù)器響應(yīng)的數(shù)據(jù)結(jié)果
6.把處理的數(shù)據(jù)更新到HTML頁面上
23.get和post有什么區(qū)別?
1.get一般是獲取數(shù)據(jù),post一般是提交數(shù)據(jù)
2.get參數(shù)會放在url上,所以安全性比較差,post是放在body中
3.get請求刷新服務(wù)器或退回是沒有影響的,post請求退回時會重新提交數(shù)據(jù)
4.get請求時會被緩存,post請求不會被緩存
5.get請求會被保存在瀏覽器歷史記錄中,post不會
6.get請求只能進(jìn)行url編碼,post請求支持很多種
24.promise的內(nèi)部原理是什么?它的優(yōu)缺點是什么?
Promise對象,封裝了一個異步操作并且還可以獲取成功或失敗的結(jié)果
Promise主要就是解決回調(diào)地獄的問題,之前如果異步任務(wù)比較多,同時他們之間有相互依賴的關(guān)系,
就只能使用回調(diào)函數(shù)處理,這樣就容易形成回調(diào)地獄,代碼的可讀性差,可維護性也很差
有三種狀態(tài):pending初始狀態(tài) fulfilled成功狀態(tài) rejected失敗狀態(tài)
狀態(tài)改變只會有兩種情況,
pending -> fulfilled; pending -> rejected 一旦發(fā)生,狀態(tài)就會凝固,不會再變
首先就是我們無法取消promise,一旦創(chuàng)建它就會立即執(zhí)行,不能中途取消
如果不設(shè)置回調(diào),promise內(nèi)部拋出的測u哦嗚就無法反饋到外面
若當(dāng)前處于pending狀態(tài)時,無法得知目前在哪個階段。
原理:
構(gòu)造一個Promise實例,實例需要傳遞函數(shù)的參數(shù),這個函數(shù)有兩個形參,分別都是函數(shù)類型,一個是resolve一個是reject
promise上還有then方法,這個方法就是來指定狀態(tài)改變時的確定操作,resolve是執(zhí)行第一個函數(shù),reject是執(zhí)行第二個函數(shù)
25.promise和async await的區(qū)別是什么?
1.都是處理異步請求的方式
2.promise是ES6,async await 是ES7的語法
3.async await是基于promise實現(xiàn)的,他和promise都是非阻塞性的
優(yōu)缺點:
1.promise是返回對象我們要用then,catch方法去處理和捕獲異常,并且書寫方式是鏈?zhǔn)?#xff0c;容易造成代碼重疊,不好維護,async await 是通過tra catch進(jìn)行捕獲異常
2.async await最大的優(yōu)點就是能讓代碼看起來像同步一樣,只要遇到await就會立刻返回結(jié)果,然后再執(zhí)行后面的操作
promise.then()的方式返回,會出現(xiàn)請求還沒返回,就執(zhí)行了后面的操作
26.瀏覽器的存儲方式有哪些?
1.cookies
H5標(biāo)準(zhǔn)前的本地存儲方式
兼容性好,請求頭自帶cookie
存儲量小,資源浪費,使用麻煩(封裝)
2.localstorage
H5加入的以鍵值對為標(biāo)準(zhǔn)的方式
操作方便,永久存儲,兼容性較好
保存值的類型被限定,瀏覽器在隱私模式下不可讀取,不能被爬蟲
3.sessionstorage
當(dāng)前頁面關(guān)閉后就會立刻清理,會話級別的存儲方式
4.indexedDB
H5標(biāo)準(zhǔn)的存儲方式,,他是以鍵值對進(jìn)行存儲,可以快速讀取,適合WEB場景
27.token存在sessionstorage還是loaclstorage?
token:驗證身份的令牌,一般就是用戶通過賬號密碼登錄后,服務(wù)端把這些憑證通過加密等一系列操作后得到的字符串
1.存loaclstorage里,后期每次請求接口都需要把它當(dāng)作一個字段傳給后臺
2.存cookie中,會自動發(fā)送,缺點就是不能跨域
如果存在localstorage中,容易被XSS攻擊,但是如果做好了對應(yīng)的措施,那么是利大于弊
如果存在cookie中會有CSRF攻擊
28.token的登錄流程。
1.客戶端用賬號密碼請求登錄
2.服務(wù)端收到請求后,需要去驗證賬號密碼
3.驗證成功之后,服務(wù)端會簽發(fā)一個token,把這個token發(fā)送給客戶端
4.客戶端收到token后保存起來,可以放在cookie也可以是localstorage
5.客戶端每次向服務(wù)端發(fā)送請求資源的時候,都需要攜帶這個token
6.服務(wù)端收到請求,接著去驗證客戶端里的token,驗證成功才會返回客戶端請求的數(shù)據(jù)
29.頁面渲染的過程是怎樣的?
DNS解析
建立TCP連接
發(fā)送HTTP請求
服務(wù)器處理請求
渲染頁面
瀏覽器會獲取HTML和CSS的資源,然后把HTML解析成DOM樹
再把CSS解析成CSSOM
把DOM和CSSOM合并為渲染樹
布局
把渲染樹的每個節(jié)點渲染到屏幕上(繪制)
斷開TCP連接
30.DOM樹和渲染樹有什么區(qū)別?
DOM樹是和HTML標(biāo)簽一一對應(yīng)的,包括head和隱藏元素
渲染樹是不包含head和隱藏元素
31.精靈圖和base64的區(qū)別是什么?
精靈圖:把多張小圖整合到一張大圖上,利用定位的一些屬性把小圖顯示在頁面上,當(dāng)訪問頁面可以減少請求,提高加載速度
base64:傳輸8Bit字節(jié)代碼的編碼方式,把原本二進(jìn)制形式轉(zhuǎn)為64個字符的單位,最后組成字符串
base64是會和html css一起下載到瀏覽器中,減少請求,減少跨域問題,但是一些低版本不支持,若base64體積比原圖片大,不利于css的加載。
32.svg格式了解多少?
基于XML語法格式的圖像格式,可縮放矢量圖,其他圖像是基于像素的,SVG是屬于對圖像形狀的描述,本質(zhì)是文本文件,體積小,并且不管放大多少倍都不會失真
1.SVG可直接插入頁面中,成為DOM一部分,然后用JS或CSS進(jìn)行操作
<svg></svg>
2.SVG可作為文件被引入
<img src="pic.svg" />
3.SVG可以轉(zhuǎn)為base64引入頁面
33.了解過JWT嗎?
JSON Web Token 通過JSON形式作為在web應(yīng)用中的令牌,可以在各方之間安全的把信息作為JSON對象傳輸
信息傳輸、授權(quán)
JWT的認(rèn)證流程
1.前端把賬號密碼發(fā)送給后端的接口
2.后端核對賬號密碼成功后,把用戶id等其他信息作為JWT 負(fù)載,把它和頭部分別進(jìn)行base64編碼拼接后簽名,形成一個JWT(token)。
3.前端每日請求時都會把JWT放在HTTP請求頭的Authorization字段內(nèi)
4.后端檢查是否存在,如果存在就驗證JWT的有效性(簽名是否正確,token是否過期)
5.驗證通過后后端使用JWT中包含的用戶信息進(jìn)行其他的操作,并返回對應(yīng)結(jié)果
簡潔、包含性、因為Token是JSON加密的形式保存在客戶端,所以JWT是跨語言的,原則上是任何web形式都支持。
34.npm的底層環(huán)境是什么?
node package manager,node的包管理和分發(fā)工具,已經(jīng)成為分發(fā)node模塊的標(biāo)準(zhǔn),是JS的運行環(huán)境
npm的組成:網(wǎng)站、注冊表、命令行工具
35.HTTP協(xié)議規(guī)定的協(xié)議頭和請求頭有什么?
1.請求頭信息:
Accept:瀏覽器告訴服務(wù)器所支持的數(shù)據(jù)類型
Host:瀏覽器告訴服務(wù)器我想訪問服務(wù)器的哪臺主機
Referer:瀏覽器告訴服務(wù)器我是從哪里來的(防盜鏈)
User-Agent:瀏覽器類型、版本信息
Date:瀏覽器告訴服務(wù)器我是什么時候訪問的
Connection:連接方式
Cookie
X-Request-With:請求方式
2.響應(yīng)頭信息:
Location:這個就是告訴瀏覽器你要去找誰
Server:告訴瀏覽器服務(wù)器的類型
Content-Type:告訴瀏覽器返回的數(shù)據(jù)類型
Refresh:控制了的定時刷新
36.說一下瀏覽器的緩存策略。
強緩存(本地緩存)、協(xié)商緩存(弱緩存)
強緩:不發(fā)起請求,直接使用緩存里的內(nèi)容,瀏覽器把JS,CSS,image等存到內(nèi)存中,下次用戶訪問直接從內(nèi)存中取,提高性能
協(xié)緩:需要像后臺發(fā)請求,通過判斷來決定是否使用協(xié)商緩存,如果請求內(nèi)容沒有變化,則返回304,瀏覽器就用緩存里的內(nèi)容
強緩存的觸發(fā):
HTTP1.0:時間戳響應(yīng)標(biāo)頭
HTTP1.1:Cache-Control響應(yīng)標(biāo)頭
協(xié)商緩存觸發(fā):
HTTP1.0:請求頭:if-modified-since 響應(yīng)頭:last-modified
HTTP1.1:請求頭:if-none-match 響應(yīng)頭:Etag
37.說一下什么是“同源策略”?
http:// www. aaa.com:8080/index/vue.js
協(xié)議 子域名 主域名 端口號 資源
同源策略是瀏覽器的核心,如果沒有這個策略就會遭受網(wǎng)絡(luò)攻擊
主要指的就是協(xié)議+域名+端口號三者一致,若其中一個不一樣則不是同源,會產(chǎn)生跨域
三個允許跨域加載資源的標(biāo)簽:img link script
跨域是可以發(fā)送請求,后端也會正常返回結(jié)果,只不過這個結(jié)果被瀏覽器攔截了!
JSONP
CORS
websocket
反向代理
38.防抖和節(jié)流是什么?
都是應(yīng)對頁面中頻繁觸發(fā)事件的優(yōu)化方案
防抖:避免事件重復(fù)觸發(fā)
使用場景:1.頻繁和服務(wù)端交互 2.輸入框的自動保存事件
節(jié)流:把頻繁觸發(fā)的事件減少,每隔一段時間執(zhí)行
使用場景:scroll事件
39.解釋一下什么是json?
JSON是一種純字符串形式的數(shù)據(jù),它本身不提供任何方法,適合在網(wǎng)絡(luò)中進(jìn)行傳輸
JSON數(shù)據(jù)存儲在.json文件中,也可以把JSON數(shù)據(jù)以字符串的形式保存在數(shù)據(jù)庫、Cookise中
JS提供了JSON.parse() JSON.stringify()
什么時候使用json:定義接口;序列化;生成token;配置文件package.json
40.當(dāng)數(shù)據(jù)沒有請求過來的時候,該怎么做?
可以在渲染數(shù)據(jù)的地方給一些默認(rèn)的值
if判斷語句
41.有沒有做過無感登錄?
1.在相應(yīng)其中攔截,判斷token返回過期后,調(diào)用刷新token的接口
2.后端返回過期時間,前端判斷token的過期時間,去調(diào)用刷新token的接口
3.寫定時器,定時刷新token接口
流程:
1.登錄成功后保存token 和 refresh_token
2.在響應(yīng)攔截器中對401狀態(tài)碼引入刷新token的api方法調(diào)用
3.替換保存本地新的token
4.把錯誤對象里的token替換
5.再次發(fā)送未完成的請求
6.如果refresh_token過期了,判斷是否過期,過期了就清楚所有token重新登錄
42.大文件上傳是怎么做的?
分片上傳:
1.把需要上傳的文件按照一定的規(guī)則,分割成相同大小的數(shù)據(jù)塊
2.初始化一個分片上傳任務(wù),返回本次分片上傳的唯一標(biāo)識
3.按照一定的規(guī)則把各個數(shù)據(jù)塊上傳
4.發(fā)送完成后,服務(wù)端會判斷數(shù)據(jù)上傳的完整性,如果完整,那么就會把數(shù)據(jù)庫合并成原始文件
斷點續(xù)傳:
服務(wù)端返回,從哪里開始 瀏覽器自己處理
三、HTML5CSS3
1.語義化的理解。
在寫HTML頁面結(jié)構(gòu)時所用的標(biāo)簽有意義
頭部用head 主體用main 底部用foot...
怎么判斷頁面是否語義化了?
把CSS去掉,如果能夠清晰的看出來頁面結(jié)構(gòu),顯示內(nèi)容較為正常
為什么要選擇語義化?
1.讓HTML結(jié)構(gòu)更加清晰明了
2.方便團隊協(xié)作,利于開發(fā)
3.有利于爬蟲和SEO
4.能夠讓瀏覽器更好的去解析代碼
5.給用戶帶來良好的體驗
2.H5C3有哪些新特性?
H5的新特性:
1.語義化的標(biāo)簽
2.新增音頻視頻
3.畫布canvas
4.數(shù)據(jù)存儲localstorage sessionstorage
5.增加了表單控件 email url search...
6.拖拽釋放API
CSS3的新特性:
1.新增選擇器:屬性選擇器、偽類選擇器、偽元素選擇器
2.增加了媒體查詢
3.文字陰影
4.邊框
5.盒子模型box-sizing
6.漸變
7.過度
8.自定義動畫
9.背景的屬性
10.2D和3D
3.rem是如何做適配的?
rem是相對長度,相對于根元素(html)的font-size屬性來計算大小,通常來做移動端的適配
rem是根據(jù)根元素font-size計算值的倍數(shù)
比如html上的font-size:16px,給div設(shè)置寬為1.5rem,1.2rem = 16px*1.2 = 19.2px.
4.解決了哪些移動端的兼容問題?
1.當(dāng)設(shè)置樣式overflow:scroll/auto時,IOS上的華東會卡頓
-webkit-overflow-scrolling:touch;
2.在安卓環(huán)境下placeholder文字設(shè)置行高時會偏上
input有placeholder屬性的時候不要設(shè)置行高
3.移動端字體小于12px時異常顯示
應(yīng)該先把在整體放大一倍,然后再用transform進(jìn)行縮小
4.ios下input按鈕設(shè)置了disabled屬性為true顯示異常
input[typy=button]{
opcity:1
}
5.安卓手機下取消語音輸入按鈕
input::-webkit-input-speech-button{
display:none
}
6.IOS下取消input輸入框在輸入引文首字母默認(rèn)大寫
<input autocapitalize='off' autocorrect='off'/>
7.禁用IOS和安卓用戶選中文字
添加全局CSS樣式:-webkit-user-select:none
8.禁止IOS彈出各種窗口
-webkit-touch-callout:none
9.禁止IOS識別長串?dāng)?shù)字為電話
添加meta屬性 <meta conten='telephone=no' name='format-detection'>
四、Vue
1.v-if和v-show的區(qū)別?
都可以控制元素的顯示和隱藏
1.v-show時控制元素的display值來讓元素顯示和隱藏;v-if顯示隱藏時把DOM元素整個添加和刪除
2.v-if有一個局部編譯/卸載的過程,切換這個過程中會適當(dāng)?shù)匿N毀和重建內(nèi)部的事件監(jiān)聽和子組件;v-show只是簡單的css切換
3.v-if才是真正的條件渲染;v-show從false變成true的時候不會觸發(fā)組件的聲明周期,v-if會觸發(fā)聲明周期
4.v-if的切換效率比較低 v-show的效率比較高
2.如何理解MVVM的?
是Model-View-ViewModel的縮寫。前端開發(fā)的架構(gòu)模式
M:模型,對應(yīng)的就是data的數(shù)據(jù)
V:視圖,用戶界面,DOM
VM:視圖模型:Vue的實例對象,連接View和Model的橋梁
核心是提供對View和ViewModel的雙向數(shù)據(jù)綁定,當(dāng)數(shù)據(jù)改變的時候,ViewModel能監(jiān)聽到數(shù)據(jù)的變化,自動更新視圖,當(dāng)用戶操作視圖的時候,ViewModel也可以監(jiān)聽到視圖的變化,然后通知數(shù)據(jù)進(jìn)行改動,這就實現(xiàn)了雙向數(shù)據(jù)綁定
ViewModel通過雙向綁定把View和Model連接起來,他們之間的同步是自動的,不需要認(rèn)為干涉,所以我們只需要關(guān)注業(yè)務(wù)邏輯即可,不需要操作DOM,同時也不需要關(guān)注數(shù)據(jù)的狀態(tài)問題,因為她是由MVVM統(tǒng)一管理
3.v-for中的key值的作用是什么?
key屬性是DOM元素的唯一標(biāo)識
作用:
1.提高虛擬DOM的更新
2.若不設(shè)置key,可能會觸發(fā)一些bug
3.為了觸發(fā)過度效果
4.說一下你對vue生命周期的理解。
組件從創(chuàng)建到銷毀的過程就是它的生命周期
創(chuàng)建
beforeCreat
在這個階段屬性和方法都不能使用
created
這里時實例創(chuàng)建完成之后,在這里完成了數(shù)據(jù)監(jiān)測,可以使用數(shù)據(jù),修改數(shù)據(jù),不會觸發(fā)updated,也不會更新視圖
掛載
beforeMount
完成了模板的編譯,虛擬DOM也完成創(chuàng)建,即將渲染,修改數(shù)據(jù),不會觸發(fā)updated
Mounted
把編譯好的模板掛載到頁面,這里可以發(fā)送異步請求也可以訪問DOM節(jié)點
更新
beforeUpdate
組件數(shù)據(jù)更新之前使用,數(shù)據(jù)是新的,頁面上的數(shù)據(jù)時舊的,組件即將更新,準(zhǔn)備渲染,可以改數(shù)據(jù)
updated
render重新做了渲染,這時數(shù)據(jù)和頁面都是新的,避免在此更新數(shù)據(jù)
銷毀
beforeDestroy
實例銷毀前,在這里實例還可以用,可以清楚定時器等等
destroyed
組件已經(jīng)被銷毀了,全部都銷毀
使用了keep-alive時多出兩個周期:
activited
組件激活時
deactivited
組件被銷毀時
5.在created和mounted去請求數(shù)據(jù),有什么區(qū)別?
created:在渲染前調(diào)用,通常先初始化屬性,然后做渲染
mounted:在模板渲染完成后,一般都是初始化頁面后,在對元素節(jié)點進(jìn)行操作
在這里請求數(shù)據(jù)可能會出現(xiàn)閃屏的問題,created里不會
一般用created比較多
請求的數(shù)據(jù)對DOM有影響,那么使用created
如果請求的數(shù)據(jù)對DOM無關(guān),可以放在mounted
6.vue中的修飾符有哪些?
1.事件修飾符
.stop 組織冒泡
.prevent 組織默認(rèn)行為
.capture 內(nèi)部元素觸發(fā)的事件先在次處理
.self 只有在event.target是當(dāng)前元素時觸發(fā)
.once 事件只會觸發(fā)一次
.passive 立即觸發(fā)默認(rèn)行為
.native 把當(dāng)前元素作為原生標(biāo)簽看待
2.按鍵修飾符
.keyup 鍵盤抬起
.keydown 鍵盤按下
3.系統(tǒng)修飾符
.ctrl
.alt
.meta
4.鼠標(biāo)修飾符
.left 鼠標(biāo)左鍵
.right 鼠標(biāo)右鍵
.middle 鼠標(biāo)中鍵
5.表單修飾符
.lazy 等輸入完之后再顯示
.trim 刪除內(nèi)容前后的空格
.number 輸入是數(shù)字或轉(zhuǎn)為數(shù)字
7.elementui是怎么做表單驗證的?
1.在表單中加rules屬性,然后再data里寫校驗規(guī)則
2.內(nèi)部添加規(guī)則
3.自定義函數(shù)校驗
8.vue如何進(jìn)行組件通信?
1.父傳子
props
父組件使用自定義屬性,然后子組件使用props
$ref
引用信息會注冊在父組件的$refs對象上
2.子傳父
$emit
子組件綁定自定義事件,觸發(fā)執(zhí)行后,傳給父組件,父組件需要用事件監(jiān)聽來接收參數(shù)
3.兄弟傳
new一個新的vue實例,用on和emit來對數(shù)據(jù)進(jìn)行傳輸
4.vuex傳值
9.keep-alive是什么?怎么使用?
Vue的一個內(nèi)置組件,包裹組件的時候,會緩存不活躍的組件實例,并不是銷毀他們
作用:把組件切換的狀態(tài)保存在內(nèi)存里,防止重復(fù)渲染DOM節(jié)點,減少加載時間和性能消耗,提高用戶體驗
10.axios是怎么做封裝的?
下載 創(chuàng)建實例 接著封裝請求響應(yīng)攔截器 拋出 最后封裝接口
11.vue路由時怎么傳參的?
params傳參
this.$router.push({name:'index',params:{id:item.id}})
this.$route.params.id
路由屬性傳參
this.$router.push({name:'/index/${item.id}'})
路由配置 { path:'/index:id' }
query傳參(可以解決頁面刷新參數(shù)丟失的問題)
this.$router.push({
name:'index',
query:{id:item.id}
})
12.vue路由的hash模式和history模式有什么區(qū)別?
1.hash的路由地址上有#號,history模式?jīng)]有
2.在做回車刷新的時候,hash模式會加載對應(yīng)頁面,history會報錯404
3.hash模式支持低版本瀏覽器,history不支持,因為是H5新增的API
4.hash不會重新加載頁面,單頁面應(yīng)用必備
5.history有歷史記錄,H5新增了pushState和replaceState()去修改歷史記錄,并不會立刻發(fā)送請求
6.history需要后臺配置
13.路由攔截是怎么實現(xiàn)的?
路由攔截 axios攔截
需要在路由配置中添加一個字段,它是用于判斷路由是否需要攔截
{
name:'index',
path:'/index',
component:Index,
meta:{
requirtAuth:true
}
}
router.beforeEach((to,from,next) => {
if(to.meta.requirtAuth){
if( store.satte.token ){
next()
}else{
}
}
})
14.說一下vue的動態(tài)路由。
要在路由配置里設(shè)置meat屬性,擴展權(quán)限相關(guān)的字段,在路由導(dǎo)航守衛(wèi)里通過判斷這個權(quán)限標(biāo)識,實現(xiàn)路由的動態(tài)增加和跳轉(zhuǎn)
根據(jù)用戶登錄的賬號,返回用戶角色
前端再根據(jù)角色,跟路由表的meta.role進(jìn)行匹配
把匹配搭配的路由形成可訪問的路由
15.如何解決刷新后二次加載路由?
1.window.location.reload()
2.matcher
const router = createRouter()
export function resetRouter(){
const newRouter = creatRouter()
router.matcher = newRouter.matcher
}
16.vuex刷新數(shù)據(jù)會丟失嗎?怎么解決?
vuex肯定會重新獲取數(shù)據(jù),頁面也會丟失數(shù)據(jù)
1.把數(shù)據(jù)直接保存在瀏覽器緩存里(cookie localstorage sessionstorage)
2.頁面刷新的時候,再次請求數(shù)據(jù),達(dá)到可以動態(tài)更新的方法
監(jiān)聽瀏覽器的刷新書簡,在刷新前把數(shù)據(jù)保存到sessionstorage里,刷新后請求數(shù)據(jù),請求到了用vuex,如果沒有那就用sessionstorage里的數(shù)據(jù)
17.computed和watch的區(qū)別?
1.computed是計算屬性,watch是監(jiān)聽,監(jiān)聽的是data中數(shù)據(jù)的變化
2.computed是支持緩存,依賴的屬性值發(fā)生變化,計算屬性才會重新計算,否則用緩存;watch不支持緩存
3.computed不支持異步,watch是可以異步操作
4.computed是第一次加載就監(jiān)聽,watch是不監(jiān)聽
5.computed函數(shù)中必須有return watch不用
18.vuex在什么場景會去使用?屬性有哪些?
state 存儲變量
getters state的計算屬性
mutations 提交更新數(shù)據(jù)的方法
actions 和mutations差不多,他是提交mutations來修改數(shù)據(jù),可以包括異步操作
modules 模塊化vuex
使用場景:
用戶的個人信息、購物車模塊、訂單模塊
19.vue的雙向數(shù)據(jù)綁定原理是什么?
通過數(shù)據(jù)劫持和發(fā)布訂閱者模式來實現(xiàn),同時利用Object.defineProperty()劫持各個屬性的setter和getter,
在數(shù)據(jù)發(fā)生改變的時候發(fā)布消息給訂閱者,觸發(fā)對應(yīng)的監(jiān)聽回調(diào)渲染視圖,也就是說數(shù)據(jù)和視圖時同步的,數(shù)據(jù)發(fā)生改變,視圖跟著發(fā)生改變,視圖改變,數(shù)據(jù)也會發(fā)生改變。
第一步:需要observer的數(shù)據(jù)對象進(jìn)行遞歸遍歷,包括子屬性對象的屬性,都加上setter和getter
第二步:compile模板解析指令,把模板中的變量替換成數(shù)據(jù),然后初始化渲染視圖,同時把每個指令對應(yīng)的節(jié)點綁定上更新函數(shù),添加訂閱者,如果數(shù)據(jù)變化,收到通知,更新視圖
第三步:Watcher訂閱者是Observer和Compile之間的通信橋梁,作用:
1.在自身實例化的時候忘訂閱器內(nèi)添加自己
2.自身要有一個update()方法
3.等待屬性變動時,調(diào)用自身的update方法,觸發(fā)compile這種的回調(diào)
第四步:MVVM作為數(shù)據(jù)綁定的入口,整合了observer、compile和watcher三者,通過observer來監(jiān)聽自己的數(shù)據(jù)變化,通過compile解析模板指令,最后利用watcher把observer和compile聯(lián)系起來,最終達(dá)到數(shù)據(jù)更新視圖更新,視圖更新數(shù)據(jù)更新的效果
20.了解diff算法和虛擬DOM嗎?
虛擬DOM,描述元素和元素之間的關(guān)系,創(chuàng)建一個JS對象
如果組件內(nèi)有響應(yīng)的數(shù)據(jù),數(shù)據(jù)發(fā)生改變的時候,render函數(shù)會生成一個新的虛擬DOM,這個新的虛擬DOM會和舊的虛擬DOM進(jìn)行比對,找到需要修改的虛擬DOM內(nèi)容,然后去對應(yīng)的真實DOM中修改
diff算法就是虛擬DOM的比對時用的,返回一個patch對象,這個對象的作用就是存儲兩個節(jié)點不同的地方,最后用patch里記錄的信息進(jìn)行更新真實DOM
步驟:
1.JS對象表示真實的DOM結(jié)構(gòu),要生成一個虛擬DOM,再用虛擬DOM構(gòu)建一個真實DOM樹,渲染到頁面
2.狀態(tài)改變生成新的虛擬DOM,跟就得虛擬DOM進(jìn)行比對,這個比對的過程就是DIFF算法,利用patch記錄差異
3.把記錄的差異用在第一個虛擬DOM生成的真實DOM上,視圖就更新了。
21.vue和jquery的區(qū)別是什么?
1.原理不同
vue就是數(shù)據(jù)綁定;jq是先獲取dom再處理
2.著重點不同
vue是數(shù)據(jù)驅(qū)動,jq是著重于頁面
3.操作不同
4.未來發(fā)展不同
22.vuex的響應(yīng)式處理。
vuex是vue的狀態(tài)管理工具
vue中可以直接觸發(fā)methods中的方法,vuex是不可以的。未來處理異步,當(dāng)觸發(fā)事件的時候,會通過dispatch來訪問actions中的方法,actions中的commit會觸發(fā)mutations中的方法從而修改state里的值,通過getter把數(shù)據(jù)更新到視圖
Vue.use(vuex),調(diào)用install方法,通過applyMixin(vue)在任意組件內(nèi)執(zhí)行this.$store就可以訪問到store對象。
vuex的state是響應(yīng)式的,借助的就是vue的data,把state存到vue實例組件的data中
23.vue中遍歷全局的方法有哪些?
1.普通遍歷,對象.forEach()
arr.forEach(function(item,index,arr){
console.log(item,index)
})
2.對元素統(tǒng)一操作 對象.map()
var newarr = arr.map(function(item){
return item+1
})
3.查找符合條件的元素 對象.filter()
arr.filter(function(item){
if(item > 2){
return false
}else{
return true
}
})
4.查詢符合條件的元素,返回索引 對象.findindex()
arr.finindex(function(item){
if(item>1){
return true
}else{
return false
}
})
對象.evening() 遇到不符合的對象會停止
對象.some() 找到符合條件的元素就停止
24.如何搭建腳手架?
下載:node cnpm webpack vue-cli
創(chuàng)建項目:
1.找到對應(yīng)的文件,然后利用node指令創(chuàng)建(cmd)
2.vue init webpack xxxx
3.回車項目描述
4.作者回車
5.選擇vue build
6.回車
7.輸入n
8.不按照yarn
9.輸入npm run dev
25.如何封裝一個組件?
1.使用Vue.extend()創(chuàng)建一個組件
2.使用Vue.components()方法注冊組件
3.如果子組件需要數(shù)據(jù),可以在props中接收定義
4.子組件修改好數(shù)據(jù),要把數(shù)據(jù)傳遞給父組件,可以用emit()方法
原則:
把功能拆開
盡量讓組件原子化,一個組件做一件事情
容器組件管數(shù)據(jù),展示組件管視圖
26.封裝一個可復(fù)用的組件,需要滿足什么條件?
1.低耦合,組件之間的依賴越小越好
2.最好從父級傳入信息,不要在公共組件中請求數(shù)據(jù)
3.傳入的數(shù)據(jù)要進(jìn)行校驗
4.處理事件的方法寫在父組件中
27.vue的過濾器怎么使用?
vue的特性,用來對文本進(jìn)行格式化處理
使用它的兩個地方,一個是插值表達(dá)式,一個是v-bind
分類:
1.全局過濾器
Vue.filter('add',function(v){
return v < 10 ? '0' + v : v
})
<div>{{33 | add}}</div>
2.本地過濾器
和methods同級
filter:{
add:function(v){
return v < 10 ? '0' + v : v
}
}
28.vue中如何做強制刷新?
1.localtion.reload()
2.this.$router.go(0)
3.provide和inject
29.vue3和vue2有哪些區(qū)別?
1.雙向數(shù)據(jù)綁定的原理不同
2.是否支持碎片
3.API不同
4.定義數(shù)據(jù)變量方法不同
5.生命周期的不同
6.傳值不同
7.指令和插槽不同
8.main.js不同
30.vue的性能優(yōu)化怎么做?
1.編碼優(yōu)化
不要把所有數(shù)據(jù)都放在data中
v-for時給每個元素綁定事件用事件代理
keep-alive緩存組件
盡可能拆分組件,提高復(fù)用性、維護性
key值要保證唯一
合理使用路由懶加載,異步組件
數(shù)據(jù)持久化存儲的使用盡量用防抖、節(jié)流優(yōu)化
2.加載優(yōu)化
按需加載
內(nèi)容懶加載
圖片懶加載
3.用戶體驗
骨架屏
4.SEO優(yōu)化
預(yù)渲染
服務(wù)端渲染ssr
5.打包優(yōu)化
CDN形式加載第三方模塊
多線程打包
抽離公共文件
6.緩存和壓縮
客戶端緩存、服務(wù)端緩存
服務(wù)端Gzip壓縮
31.首屏優(yōu)化該如何去做?
1.使用路由懶加載
2.非首屏組件使用異步組件
3.首屏不中要的組件延遲加載
4.靜態(tài)資源放在CDN上
5.減少首屏上JS、CSS等資源文件的大小
6.使用服務(wù)端渲染
7.簡歷減少DOM的數(shù)量和層級
8.使用精靈圖請求
9.做一些loading
10.開啟Gzip壓縮
11.圖片懶加載
32.vue3的性能為什么比vue2好?
1.diff算法的優(yōu)化
2.靜態(tài)提升
3.事件偵聽緩存
33.vue3為什么使用proxy?
1.proxy可以代理整個對象,defineproperty只代理對象上的某個屬性
2.proxy對代理對象的監(jiān)聽更加豐富
3.proxy代理對象會生成新的對象,不會修改被代理對象本身
4.proxy補兼容ie瀏覽器
34.說一下你對組件的理解。
可以重復(fù)使用的vue實例,獨一無二的組件名稱
可以抽離單獨的公共模塊
提高代碼的復(fù)用率
35.你是如何規(guī)劃項目文件的?
public
圖標(biāo)、index.html、img
src
api
assets
components
按分類再次劃分子目錄
plugins
router
static
styles
utils
views
App.vue
main.js
package.json
vue.config.js
36.是否使用過nuxt.js?
是基于vue的應(yīng)用框架,關(guān)注的是渲染,可以開發(fā)服務(wù)端渲染應(yīng)用的配置
SSR:服務(wù)端渲染
好處:
SSR生成的是有內(nèi)容的HTML頁面,有利于搜索引擎的搜索
優(yōu)化了首屏加載時間
SEO:優(yōu)化搜索引擎
SPA的應(yīng)用不利于搜索引擎SEO的操作
37.SEO如何優(yōu)化?
1.SSR
2.預(yù)渲染 prerender-spa-plugin
?
五、Echarts
1.echarts有用過嗎?常用的組件有哪些?
title標(biāo)題組件 show text link
toolbox工具欄 導(dǎo)出圖片 數(shù)據(jù)視圖 切換 縮放 show orient feature
tooltip tigger 觸發(fā)類型
markPoint標(biāo)注點
markLine圖標(biāo)的標(biāo)線
六、Uni-APP
1.uni-app有沒有做過分包?
優(yōu)化小程序的下載和啟動速度
小程序啟動默認(rèn)下載主包并啟動頁面,當(dāng)用戶進(jìn)入分包時,才會下載對應(yīng)的分包,下載完進(jìn)行展示
七、Weabpack
1.webpack打包和不打包的區(qū)別?
1.運行效率
2.對基礎(chǔ)的支持不夠
2.webpack是怎么打包的,babel是做什么的?
webpack會把js css image看作一個模塊,用import/require引入
找到入口文件,通過入口文件找到關(guān)聯(lián)的依賴文件,把他們打包到一起
把bundle文件,拆分成多個小的文件,異步按需加載所需要的文件
如果一個被多個文件引用,打包時只會生成一個文件
如果引用的文件沒有調(diào)用,不會打包,如果引入的變量和方法沒有調(diào)用也不會打包
對于多個入口文件,加入引入了相同的代碼,可以用插件把他抽離到公共文件中
八、Git
1.git如何合并、拉取代碼?
拉取代碼 git pull '倉庫地址'
查看狀態(tài) git sattus
提交到本地緩存區(qū) git add .
提交本地倉庫 git commit -m '修改描述'
提交到遠(yuǎn)程倉庫 git push '倉庫地址' master
創(chuàng)建分支 git branch -b xxx
合并分支 git merge '合并分支的名字'
2.git如何解決沖突問題?
1.兩個分支中修改了同一個文件
2.兩個分支中修改了同一個文件的名字
1.解決:當(dāng)前分支上,直接修改代碼 add commit
2.解決:在本地當(dāng)前分支上,修改沖突代碼 add commit push
九、HR
1.你的離職原因是什么?
疫情 社保 薪資問題 個人發(fā)展 技術(shù)提升 家庭因素
2.工作到現(xiàn)在,項目中遇到最難的問題是什么?怎么解決的?
1.不要回答,沒有問題
2.不要說一些常見的簡單的問題,比如:數(shù)據(jù)請求不過來、渲染頁面時出現(xiàn)了問題、跳轉(zhuǎn)路由不會...
首先應(yīng)該時自行去查找資料尋求解決辦法,然后再去請教同時或者組長
3.你的優(yōu)勢在哪里?
1.盡量不要暴露自己的缺點
2.不要過度美化自己
4.如何協(xié)同工作?
1.開發(fā)前會開個會議,最后形成一個開發(fā)文檔
2.利用工具保證項目的正常進(jìn)度,規(guī)范化