1、v-model默認的觸發(fā)條件是input事件,加了.lazy修飾符之后,v-model會在change事件觸發(fā)的時候去監(jiān)聽
2、:class 綁定變量 綁定對象 綁定一個數(shù)組 綁定三元表達式
:style 綁定變量 綁定對象 綁定函數(shù)返回值 綁定三元表達式
3、 組件中寫name選項有什么作用
- 項目使用keep-alive時,可搭配組件name進行緩存過濾
- DOM做遞歸組件時需要調(diào)用自身name
- vue-devtools調(diào)試工具里顯示的組見名稱是由vue中組件name決定的
4、diff算法
(key的體現(xiàn):不設key,newCh和oldCh只會進行頭尾兩端的相互比較,設key后,除了頭尾兩端的比較外,還會從用key生成的對象oldKeyToIdx中查找匹配的節(jié)點,所以為節(jié)點設置key可以更高效的利用dom。)
diff的過程就是調(diào)用patch函數(shù),就像打補丁一樣修改真實dom。
function patch (oldVnode, vnode) {
if (sameVnode(oldVnode, vnode)) {
patchVnode(oldVnode, vnode)
} else {
const oEl = oldVnode.el
let parentEle = api.parentNode(oEl) //取得oldvnode.el的父節(jié)點,parentEle是真實dom
createEle(vnode) //createEle(vnode)會為vnode創(chuàng)建它的真實dom,令vnode.el =真實dom
if (parentEle !== null) {
api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl)) //parentEle將新的dom插入,移除舊的dom
api.removeChild(parentEle, oldVnode.el)
oldVnode = null
}
}
return vnode
function sameVnode (a, b) {
return (
a.key === b.key && // key值
a.tag === b.tag && // 標簽名
a.isComment === b.isComment && // 是否為注釋節(jié)點
// 是否都定義了data,data包含一些具體信息,例如onclick , style
isDef(a.data) === isDef(b.data) &&
sameInputType(a, b) // 當標簽是<input>的時候,type必須相同
)
}
如果兩個節(jié)點是一樣的,那么就深入檢查他們的子節(jié)點。如果兩個節(jié)點不一樣那就可以直接替換oldVnode:
當我們確定兩個節(jié)點相同之后我們會對兩個節(jié)點執(zhí)行patchVnode方法:
當兩個節(jié)點值得比較時
function patchVnode (oldVnode, vnode) {
const el = vnode.el = oldVnode.el
let i, oldCh = oldVnode.children, ch = vnode.children
if (oldVnode === vnode) return
if (oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text) {
api.setTextContent(el, vnode.text)
}else {
updateEle(el, vnode, oldVnode)
if (oldCh && ch && oldCh !== ch) {
updateChildren(el, oldCh, ch)
}else if (ch){
createEle(vnode) //create el's children dom
}else if (oldCh){
api.removeChildren(el)
}
}
}
這個函數(shù)做了以下事情:
找到對應的真實dom,稱為el
判斷Vnode和oldVnode是否指向同一個對象,如果是,那么直接return
如果他們都有文本節(jié)點并且不相等,那么將el的文本節(jié)點設置為Vnode的文本節(jié)點。
如果oldVnode有子節(jié)點而Vnode沒有,則刪除el的子節(jié)點
如果oldVnode沒有子節(jié)點而Vnode有,則將Vnode的子節(jié)點真實化之后添加到el
如果兩者都有子節(jié)點,則執(zhí)行updateChildren函數(shù)比較子節(jié)點,這一步很重要
對比當前真實的DOM和虛擬DOM,在對比過程中直接更新真實DOM
只對比同一層級的變化
節(jié)點比較時有5中情況
- if (oldVnode === vnode),他們的引用一致,可以認為沒有變化。
- if(oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text),文本節(jié)點的比較,需要修改,則會調(diào)用Node.textContent = vnode.text。
- if( oldCh && ch && oldCh !== ch ), 兩個節(jié)點都有子節(jié)點,而且它們不一樣,這樣我們會調(diào)用updateChildren函數(shù)比較子節(jié)點,這是diff的核心,后邊會講到。
- else if (ch),只有新的節(jié)點有子節(jié)點,調(diào)用createEle(vnode),vnode.el已經(jīng)引用了老的dom節(jié)點,createEle函數(shù)會在老dom節(jié)點上添加子節(jié)點。
- else if (oldCh),新節(jié)點沒有子節(jié)點,老節(jié)點有子節(jié)點,直接刪除老節(jié)點。
首屏加載優(yōu)化
- 異步路由和異步加載
- 還有分屏加載, 按需加載, 延時加載圖片等, cdn, 域名拆分
- webpack壓縮HTML/CSS/JS,
- 首屏css單獨提取內(nèi)聯(lián),
- 關(guān)鍵資源Proload,
- 圖片:不縮放,使用webp、小圖片base64(3k大小,太大的話會增加css文件大小,Base64 跟 CSS 混在一起,大大增加了瀏覽器需要解析CSS樹的耗時。),iconfont,
- gzip,
dns-prefetch, - 靜態(tài)資源單獨域名,去掉cookie
- 將資源放到不同的域下:瀏覽器同時從一個域下載資源的數(shù)目有限(chrome為6個),增加域可以提高并行下載量
- 減少回流重繪
事件捕獲和事件冒泡
http://m.itdecent.cn/p/c88c15c6074c
封裝axios主要封裝
封裝處理配置(路徑、時間、token)、統(tǒng)一管理接口、錯誤處理、不同形式的請求、消息提示、loading等。
div水平垂直居中
- 使用flex布局
div.parent {
display: flex;
justify-content: center;
align-items: center;
}
}
- 子元素絕對定位
div.parent {
position: relative;
}
}
div.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
- 知道子元素高度的情況下
/* 或者 */
div.child {
width: 50px;
height: 10px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -25px;
margin-top: -5px;
}
}
/* 或 */
div.child {
width: 50px;
height: 10px;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
}
div.parent {
display: grid;
}
}
div.child {
justify-self: center;
align-self: center;
}
}
div.parent {
font-size: 0;
text-align: center;
&::before {
content: "";
display: inline-block;
width: 0;
height: 100%;
vertical-align: middle;
}
}
}
div.child{
display: inline-block;
vertical-align: middle;
}
}
5
div.parent{
display:flex;
}
}
div.child{
margin:auto;
}
}
computed原理
在initComputed中遍歷每一個computed屬性,創(chuàng)建對應的Watcher。在Watcher實例化過程中,計算computed屬性結(jié)果,會對依賴的data進行取值,從而觸發(fā)data的getter進行依賴收集,將當前Watcher加入到訂閱者數(shù)組中。當computed屬性依賴的data改變時,會觸發(fā)data的setter通知訂閱者更新,這個computed會重新計算。
淺拷貝是拷貝一層,深層次的對象級別的就拷貝引用;深拷貝是拷貝多層,每一級別的數(shù)據(jù)都會拷貝出來;
箭頭函數(shù)和普通函數(shù)的區(qū)別
1、箭頭函數(shù)是匿名函數(shù),不能作為構(gòu)造函數(shù),即不能使用new來創(chuàng)建對象
2、箭頭函數(shù)不能綁定arguments,需要用類似語法來實現(xiàn) (...a)=>{拿到的是一個數(shù)組}
3、箭頭函數(shù)沒有原型屬性
4、箭頭函數(shù)沒有自己的this
flex布局
flex-container有6個屬性,包括flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content
其中
1、flex-direction主要來定義主軸的方向(默認我為row,還有row-reverse、column、column-reverse)
2、flex-wrap主要定義是否換行(默認nowrap、wrap、wrap-reverse)
3、flex-flow是flex-direction和flex-wrap的集合
4、justify-content用來定義項目在主軸上的對齊方式(flex-start,flex-end,center,space-between,space-around(2倍),space-evenly(均分))
5、align-items用來定義項目在交叉軸上如何對齊(flex-start,flex-end,center,baseline,stretch(默認值,如果item沒有高度則會拉伸至整個container高度))
baseline是以文本基線來對齊的(項目的第一行文字的基線對齊)
6、align-content決定了多行的flex-items在交叉軸上的對齊方式。
和justify-content類似,不過軸換成了交叉軸
每一個item上也有6個屬性,分別為order、flex-grow、flex-shrink、flex-basis、flex、align-self
(1)其中order定義每個item的排列順序,數(shù)值越小排列越靠前
(2)flex-grow定義項目的放大比例,默認為0,即如果存在剩余空間也不放大。
flex-grow決定了items如何擴展,當flex container在主軸方向上有剩余size的時候flex-grow才會生效。
----若所有items的flex-grow總和sum超過1,每個flex item擴展的size為剩余的sizeflex-grow/num
----若總和不超過1,每個item擴展的size為剩余的sizeflex-grow
前端安全:
xss攻擊,sql注入,CSRF攻擊
前端性能優(yōu)化
(1)資源的合并于壓縮html壓縮,css壓縮,js壓縮與混亂,公共文件合并
(2)服務端開啟gzip
(3)懶加載 預加載
(4)緩存,分級緩存
200(from cache): 由expires / cache-control 控制。expires(http1.0有效)是絕對時間;cache-control(http1.1有效)是相對時間。兩者都存在時,cache-control 覆蓋 expires,只要沒有失效,瀏覽器只訪問自己的緩存。
304 : 由 last-modified / etag 控制。當上一層失效時或用戶點擊refresh,F(xiàn)5時,瀏覽器就會發(fā)送請求給服務器,如果服務器端沒有變化,則返回304給瀏覽器。
200 :當瀏覽器本身沒有緩存或者上一層失效時,或者用戶點擊了CTL + F5 時,瀏覽器直接去服務器下載最新數(shù)據(jù)。
url從輸入到呈現(xiàn)經(jīng)歷的步驟。(性能優(yōu)化)
1、瀏覽器查緩存,有直接返回,沒有則從服務器取。
2、解析協(xié)議,主機,端口,path,開啟網(wǎng)絡線程
(每一個tab頁面可以看作是瀏覽器內(nèi)核進程,然后這個進程是多線程的,它有幾大類子線程)
- GUI線程
- JS引擎線程
- 事件觸發(fā)線程
- 定時器線程
- 網(wǎng)絡請求線程
3、組裝http報文
4、瀏覽器獲取主機ip地址(dns 瀏覽器、本機、hosts)
DNS Prefetch 是讓具有此屬性的域名不需要用戶點擊鏈接就在后臺解析,而域名解析和內(nèi)容載入是串行的網(wǎng)絡操作,所以這個方式能減少用戶的等待時間,提升用戶體驗 。
5、拿到主機地址后,打開一個socket與主機建立三次握手
6、建立成功后發(fā)送http請求
7、服務器接收請求報文并解析。(若請求頭中包含緩存驗證,如果命中則返回304狀態(tài)碼)
8、服務器將相應報文返回瀏覽器
9、瀏覽器檢查報文頭中緩存信息,確認是否緩存
10、如果是gzip則先解碼,后根據(jù)資源類型決定如何處理
11、解析html文檔。
構(gòu)建dom樹,
解析過程中遇到圖片、樣式表、js文件則啟動下載
構(gòu)建cssom樹
根據(jù)dom和cssom樹構(gòu)建渲染樹(從dom樹的根節(jié)點遍歷所有可見節(jié)點)
for in和for of
for ... in 循環(huán)返回的值都是數(shù)據(jù)結(jié)構(gòu)的 鍵值名。
遍歷對象返回的對象的key值,遍歷數(shù)組返回的數(shù)組的下標(key)。
for ... in 循環(huán)不僅可以遍歷數(shù)字鍵名,還會遍歷原型上的值和手動添加的其他鍵。如——例3
特別情況下, for ... in 循環(huán)會以任意的順序遍歷鍵名
總結(jié)一句: for in 循環(huán)特別適合遍歷對象。
for of 循環(huán)用來獲取一對鍵值對中的值,而 for in 獲取的是 鍵名
一個數(shù)據(jù)結(jié)構(gòu)只要部署了 Symbol.iterator 屬性, 就被視為具有 iterator接口, 就可以使用 for of循環(huán)。
例1這個對象,沒有 Symbol.iterator這個屬性,所以使用 for of會報 obj is not iterable
for of 不同與 forEach, 它可以與 break、continue和return 配合使用,也就是說 for of 循環(huán)可以隨時退出循環(huán)。
提供了遍歷所有數(shù)據(jù)結(jié)構(gòu)的統(tǒng)一接口
html全局屬性
clas contenteditable (h5新加) dir(元素中文字的方向) id hidden spellcheck (表明瀏覽器是否應該對元素的內(nèi)容進行拼寫檢查) style title
meta中viewpoint的作用
如果不定義viewpoint的話,頁面寬度以屏幕分辨率為基準,而設置以后可以根據(jù)設備寬度來調(diào)整頁面,達到適配終端大小的效果
css加載方式
1、外部樣式表 style link
2、內(nèi)部樣式style里寫樣式
3、@import引入
4、內(nèi)聯(lián)樣式,即直接在標簽里寫
inline元素特點
inline元素的margin和padding屬性,水平方向的padding-left, padding-right, margin-left, margin-right都產(chǎn)生邊距效果;但豎直方向的padding-top, padding-bottom, margin-top, margin-bottom不會產(chǎn)生邊距效果。
Object.create()方法創(chuàng)建一個新對象,使用現(xiàn)有對象來提供新創(chuàng)建的對象的proto
document
document.ready 和 window.onload 的區(qū)別是:上面定義的document.ready方法在DOM樹加載完成后就會執(zhí)行,而window.onload是在頁面資源(比如圖片和媒體資源,它們的加載速度遠慢于DOM的加載速度)加載完成之后才執(zhí)行。也就是說$(document).ready要比window.onload先執(zhí)行。
js繼承的6種方式
- 原型鏈繼承
function Person(name){
this.name = name
}
function Son(){
this.name = "son"
}
Son.prototype = new Person()
重點:讓新實例的原型等于父類的實例。
特點:1、實例可繼承的屬性有:實例的構(gòu)造函數(shù)的屬性,父類構(gòu)造函數(shù)屬性,父類原型的屬性。(新實例不會繼承父類實例的屬性?。?缺點:1、新實例無法向父類構(gòu)造函數(shù)傳參。
2、繼承單一。
3、所有新實例都會共享父類實例的屬性。(原型上的屬性是共享的,一個實例修改了原型屬性,另一個實例的原型屬性也會被修改?。?
- 借用構(gòu)造函數(shù)繼承
func Son(){
Person.call(this,'son2')
}
重點:用.call()和.apply()將父類構(gòu)造函數(shù)引入子類函數(shù)(在子類函數(shù)中做了父類函數(shù)的自執(zhí)行(復制))
特點:1、只繼承了父類構(gòu)造函數(shù)的屬性,沒有繼承父類原型的屬性。
2、解決了原型鏈繼承缺點1、2、3。
3、可以繼承多個構(gòu)造函數(shù)屬性(call多個)。
4、在子實例中可向父實例傳參。
缺點:1、只能繼承父類構(gòu)造函數(shù)的屬性。
2、無法實現(xiàn)構(gòu)造函數(shù)的復用。(每次用每次都要重新調(diào)用)
3、每個新實例都有父類構(gòu)造函數(shù)的副本,臃腫。
- 組合繼承(組合原型鏈繼承和借用構(gòu)造函數(shù)繼承)(常用)
function Son(name){
Person.call(this, name)
}
Son.prototype = new Person()
重點:結(jié)合了兩種模式的優(yōu)點,傳參和復用
特點:1、可以繼承父類原型上的屬性,可以傳參,可復用。
2、每個新實例引入的構(gòu)造函數(shù)屬性是私有的。
缺點:調(diào)用了兩次父類構(gòu)造函數(shù)(耗內(nèi)存),子類的構(gòu)造函數(shù)會代替原型上的那個父類構(gòu)造函數(shù)。
- 最完美的繼承
function Parent4(){
this.name = "parent4";
this.colors = ["red","blue","yellow"];
}
Parent4.prototype.sex = "男";
Parent4.prototype.say = function(){console.log("Oh, My God!")}
function Child4(){
Parent4.call(this);
this.type = "child4";
}
Child4.prototype = Object.create(Parent4.prototype);
Child4.prototype.constructor = Child4;
//Object.create是一種創(chuàng)建對象的方式,它會創(chuàng)建一個中間對象
清除浮動
.clearfix:after,.clearfix:before{
content: "";
display: table;
}
.clearfix:after{
clear: both;
}
.clearfix:after{/偽元素是行內(nèi)元素 正常瀏覽器清除浮動方法/
content: "";
display: block;
height: 0;
clear:both;
visibility: hidden;
}
.clearfix{
zoom: 1;/ie6清除浮動的方式 號只有IE6-IE7執(zhí)行,其他瀏覽器不執(zhí)行/
}
typeof除了null以外都可以顯示正確的類型,對象和數(shù)組都返回object
instanceof主要來判斷引用類型,原理是根據(jù)原型鏈來查找。
除了undefined、null、false、NaN、''、0、-0以外的值都會被轉(zhuǎn)為true,包括所有的引用類型,即使是空的。
promise構(gòu)造函數(shù)內(nèi)的代碼是同步執(zhí)行的,之后的then或catch方式是異步執(zhí)行的。構(gòu)造函數(shù)接收兩個參數(shù),resolve和reject。
eventloop的理解
js的執(zhí)行機制簡單來說就是先執(zhí)行同步代碼,然后執(zhí)行異步代碼,而異步代碼里又分為宏任務代碼和微任務代碼,先執(zhí)行微任務,然后執(zhí)行宏任務。
- 將所有js作為一個宏任務,遇到同步代碼就執(zhí)行,然后開始分配任務,遇到宏任務就把他們的回調(diào)分配到宏任務的隊列里,遇到微任務就把他們的回調(diào)分配到微任務的隊列里,然后開始執(zhí)行所有的微任務。
- 執(zhí)行微任務的過程還是遵循先同步然后分配異步任務的順序,微任務執(zhí)行完畢之后,一次eventloop的tick就完成了。接著挨個去執(zhí)行分配好的宏任務,在每個宏任務里又先同步后異步分配任務,完成下一次tick,循環(huán)往復
34、瀏覽器或元素的各種距離參數(shù)。
解決跨域
- jsonp
- 設置頭部Access-Control-Allow-Origin
===運算符判斷相等的流程是怎樣的
- 如果兩個值不是相同類型,它們不相等
- 如果兩個值都是 null 或者都是 undefined,它們相等
- 如果兩個值都是布爾類型 true 或者都是 false,它們相等
- 如果其中有一個是NaN,它們不相等
- 如果都是數(shù)值型并且數(shù)值相等,他們相等, -0 等于 0
- 如果他們都是字符串并且在相同位置包含相同的 16 位值,他它們相等;如果在長度或者內(nèi)容上不等,它們不相等;兩個字符串顯示結(jié)果相同但是編碼不同==和===都認為他們不相等
如果他們指向相同對象、數(shù)組、函數(shù),它們相等;如果指向不同對象,他們不相等
==運算符判斷相等的流程是怎樣的
- 如果兩個值類型相同,按照===比較方法進行比較
- 如果類型不同,使用如下規(guī)則進行比較
- 如果其中一個值是 null,另一個是 undefined,它們相等
- 如果一個值是數(shù)字另一個是字符串,將字符串轉(zhuǎn)換為數(shù)字進行比較
- 如果有布爾類型,將true 轉(zhuǎn)換為 1,false 轉(zhuǎn)換為 0,然后用==規(guī)則繼續(xù)比較
- 如果一個值是對象,另一個是數(shù)字或字符串,將對象轉(zhuǎn)換為原始值然后用==規(guī)則繼續(xù)比較
其他所有情況都認為不相等(例如a = {} , a=="[object Object]"就返回true)
38、cookie 屬性有名,值,max-age,path, domain,secure;
進行網(wǎng)站性能優(yōu)化
dns方面
1、減少dns查詢
2、DNS Prefetch 是讓具有此屬性的域名不需要用戶點擊鏈接就在后臺解析,而域名解析和內(nèi)容載入是串行的網(wǎng)絡操作,所以這個方式能減少用戶的等待時間,提升用戶體驗 。content 方面
1.減少http請求(雪碧圖,小圖片base64)
2.組件懶加載
3.前后端進行數(shù)據(jù)交互時盡量使用json格式,數(shù)據(jù)處理方便,資源偏小。server方面
1.添加 Expires 或者 Cache-Control(max-age、no-store、no-cache、public、private) 響應頭
2.開啟gzip
3.避免空 src 的 img 標簽(當 <link> 標簽的 href 屬性為空,或 <script>、<img>、<iframe> 標簽的 src 屬性為空時,瀏覽器在渲染的過程中仍會將 href 屬性或 src 屬性中的空內(nèi)容進行加載,直至加載失敗,這樣就阻塞了頁面中其他資源的下載進程,而且最終加載到的內(nèi)容是無效的,因此要盡量避免。)cookie方面
1、去除沒有必要的cookie,如果網(wǎng)頁不需要cookie就完全禁掉。
靜態(tài)資源和主頁面不同域,加載靜態(tài)資源的HTTP請求就不會帶上主頁面中的cookie等數(shù)據(jù),減少了數(shù)據(jù)傳輸量,節(jié)省流量,提升上傳效率。
2、將cookie的大小減到最小。
由于cookie在訪問對應域名下的資源時都會通過HTTP請求發(fā)送到服務器,因此,減小cookie的大小,能減小HTTP請求報文的大小,提高響應速度。
3、設置合適的過期時間,較長的過期時間可以提高響應速度。
給cookie添加一個過期時間,則cookie信息將存儲到硬盤上,即使瀏覽器退出Cookie還會存在。只要Cookie未被清除且還在過期時間內(nèi),該Cookie就會在訪問對應域名時發(fā)送給服務器。
4、通過使用不同的domain減少cookie的使用。
cookie在訪問對應域名下的資源時都會通過HTTP請求發(fā)送到服務器,但在訪問一些資源,如js,css和圖片時,大多數(shù)情況下cookie是多余的,可以使用不同的domain來存儲這些靜態(tài)資源,這樣訪問這些資源時就不會發(fā)送多余的cookie,從而提高響應速度。css
1.將樣式表放到頁面頂部
原理:
CSS的下載是按照其在文檔中出現(xiàn)的順序進行的,所以很容易想到將不需立即使用的CSS,如彈出框CSS,放在底部,這似乎可以得到一個加載很快的頁面。然而這其實是錯誤的,IE8及以下瀏覽器的工作方式是:為了避免樣式變化導致頁面重繪or重排,會阻塞內(nèi)容呈現(xiàn),在所有CSS加載并解析完之前不會呈現(xiàn)內(nèi)容,導致整個瀏覽器顯示空白,出現(xiàn)“白屏”(瀏覽器呈現(xiàn)過程:先出現(xiàn)白屏,后出現(xiàn)文字,圖片,最后出現(xiàn)樣式),直到CSS加載完畢。若在網(wǎng)速非常慢的情況下,CSS下載時間會特別長,導致瀏覽器“白屏”的時間很長,用戶體驗會非常差。
將CSS放在底部,頁面可以逐步呈現(xiàn),但在CSS下載并解析完畢后,已經(jīng)呈現(xiàn)的文字和圖片就要需要根據(jù)新的樣式重繪,這是一種不好的用戶體驗。
2.不使用表達式
3.不使用@import
4.盡量避免回流。
引起回流包括
1).頁面渲染初始化
2).DOM結(jié)構(gòu)改變,比如刪除了某個節(jié)點
3).render樹變化,比如減少了padding
4).窗口resize
5).改變字體大小
優(yōu)化方案:
減少逐項更改樣式,最好一次性更改style,或者將樣式定義為class并一次性更新
避免循環(huán)操作dom,創(chuàng)建一個documentFragment或div,在它上面應用所有DOM操作,最后再把它添加到window.document
避免多次讀取offset等屬性。無法避免則將它們緩存到變量
將復雜的元素絕對定位或固定定位,使得它脫離文檔流,否則回流代價會很高js
1.將腳本放到頁面底部
script全部放在head中會出現(xiàn)的問題:
在需要操作body中的某元素時,可能找不到該元素,因此,若要放在head中,一般需要綁定一個監(jiān)聽windows.οnlοad=function(){ ... },當文檔全部解析完之后再執(zhí)行script代碼。
2.將 javascript 和 css 從外部引入
3.壓縮圖片方面
1.保證 favicon.ico 小并且可緩存
css
1.transform可以設置的屬性translate,translate3的,scale,rotate,skewX
2.CSS3新增了三個邊框?qū)傩裕謩e是border-radius、box-shadow和border-image。border-radius可以創(chuàng)建圓角邊框,box-shadow可以為元素添加陰影,border-image可以使用圖片來繪制邊框。IE9+支持border-radius和box-shadow屬性。Firefox、Chrome以及Safari支持所有新的邊框?qū)傩浴?br>
3.css優(yōu)先級內(nèi)聯(lián)樣式 > ID 選擇器 > 類選擇器 = 屬性選擇器 = 偽類選擇器 > 元素(類型)選擇器 = 偽元素選擇器 !important 權(quán)重最高
4.字體單位
- px
px就是pixel像素的縮寫,相對長度單位,網(wǎng)頁設計常用的基本單位。像素px是相對于顯示器屏幕分辨率而言的 - em
em是相對長度單位。相對于當前對象內(nèi)文本的字體尺寸(參考物是父元素的font-size)
如當前父元素的字體尺寸未設置,則相對于瀏覽器的默認字體尺寸
特點:
1. em的值并不是固定的;
2. em會繼承父級元素的字體大小 - rem(移動端)
rem是CSS3新增的一個相對單位,rem是相對于HTML根元素的字體大?。╢ont-size)來計算的長度單位
如果你沒有設置html的字體大小,就會以瀏覽器默認字體大小,一般是16px - vw、vh
vw、vh、vmax、vmin這四個單位都是基于視口
vw是相對視口(viewport)的寬度而定的,長度等于視口寬度的1/100
假如瀏覽器的寬度為200px,那么1vw就等于2px(200px/100)
vh是相對視口(viewport)的高度而定的,長度等于視口高度的1/100
假如瀏覽器的高度為500px,那么1vh就等于5px(500px/100)
vmin和vmax是相對于視口的高度和寬度兩者之間的最小值或最大值
5.box-sizing屬性用來控制元素的盒子模型的解析模式,默認為content-box。
context-box:W3C的標準盒子模型,設置元素的height/width屬性指的是content部分的高/寬;border-box:IE傳統(tǒng)盒子模型。設置元素的height/width屬性指的是border + padding + content部分的高/寬。
6.偽類和偽元素
偽類:用于已有元素處于某種狀態(tài)時為其添加對應的樣式,這個狀態(tài)是根據(jù)用戶行為而動態(tài)變化的。例如:當用戶懸停在指定元素時,可以通過:hover來描述這個元素的狀態(tài),雖然它和一般css相似,可以為已有元素添加樣式,但是它只有處于DOM樹無法描述的狀態(tài)下才能為元素添加樣式,所以稱為偽類。
狀態(tài)偽類:
1 :link
選擇未訪問的鏈接
2 :visited
選擇已訪問的鏈接
3 :hover
選擇鼠標指針浮動在其上的元素
4 :active
選擇活動的鏈接
5 :focus
選擇獲取焦點的輸入字段
偽元素:用于創(chuàng)建一些不在DOM樹中的元素,并為其添加樣式。例如,我們可以通過:before來在一個元素之前添加一些文本,并為這些文本添加樣式,雖然用戶可以看見這些文本,但是它實際上并不在DOM文檔中。
6::checked
其他:
遇到有defer屬性的script標簽,瀏覽器繼續(xù)往下面解析頁面,且會并行下載script標簽的外部js文件,解析完HTML頁面,再執(zhí)行剛下載的js腳本(在DOMContentLoaded事件觸發(fā)前執(zhí)行,即剛剛解析完</html>,且可保證執(zhí)行順序就是他們在頁面上的先后順序)
遇到有sync屬性的script標簽,會繼續(xù)往下解析,并且同時另開進程下載腳本,腳本下載完畢,瀏覽器停止解析,開始執(zhí)行腳本,執(zhí)行完畢后繼續(xù)往下解析
為什么移動端會產(chǎn)生1px問題呢?
因為UI設計師在最初設計的時候使用的尺寸是按照640x960設計的,前端寫的時候是按照320x480寫的,寫1px(css),瀏覽器自動變成2px(真實像素)。
那么前端工程師為什么不能直接寫0.5px(css)呢?
因為在老版本的系統(tǒng)里寫0.5px(css)的話,會被瀏覽器解讀為0px(css),就沒有邊框了。不過在新版的系統(tǒng)里,已經(jīng)開始逐漸支持0.5px(css)這種寫法。所以如果設計師在大圖上設計了一個1px(真實像素)的線的話,前端工程師直接除以2,寫0.5px(css)就好了。
設置viewpoint來解決<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
webpack常用loader和插件
loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉(zhuǎn)換為 webpack 能夠處理的有效模塊,然后你就可以利用 webpack 的打包能力,對它們進行處理。
這么說loaders負責的是處理源文件的如css、jsx,一次處理一個文件。而plugins并不是直接操作單個文件,它直接對整個構(gòu)建過程起作用
1、樣式解析
2、file-loader、url-loader
file-loader可以解析項目中的url引入(不僅限于css),根據(jù)我們的配置,將圖片拷貝到相應的路徑,再根據(jù)我們的配置,修改打包后文件引用路徑,使之指向正確的文件。
url-loader 功能與 file-loader 相似,但是如果文件小于一個 指定的大小他可以返回一個 DataURL。
3、mini-css-extract-plugin將css提取為單獨的文件
4、uglify-webpack-plugin壓縮代碼
5、optimize-css-assets-webpack-plugin優(yōu)化壓縮css資源
6、HTMLWebpackPlugin,將style插入到html
其他:
vue大概流程
一、主要步驟
1.初始化
vue初始化init的過程包含生命周期、事件、props、methods、data、computed與watch等的初始化
其中最主要的兩個步驟是watch的初始化和data屬性的observer過程,兩個過程是實現(xiàn)響應式和依賴收集
2.編譯
編譯是將template轉(zhuǎn)變?yōu)閞ender function 的過程,包括:解析/優(yōu)化/生成三個步驟
解析:template->AST(抽象語法樹)
優(yōu)化:標記AST中的靜態(tài)(static)節(jié)點
生成:AST->render function
3.render function 執(zhí)行
render function 執(zhí)行后生成虛擬節(jié)點樹(VNode DOM Tree)
4.渲染展現(xiàn)頁面
二、依賴收集過程
整體的流程圖中render function 執(zhí)行開始的綠色箭頭指向的流程為依賴收集過程
1.render function 執(zhí)行中會依此調(diào)用使用到的data.attr的get方法
2.get方法調(diào)用Dep.add將Vue對象中的watch加入到attr.Dep數(shù)組里
3.整個頁面渲染完畢后,所有需要使用attr的組件Vue對象的watch都收集到attr.Dep,attr.Dep內(nèi)容即為template與data的依賴關(guān)系(attr是隨便起的一個組件名)
三、響應式原理
整體流程圖中attr.set()執(zhí)行開始的紅色箭頭指向的流程為響應式原理
1.對data.attr賦值即調(diào)用attr.set方法
2.attr.set會調(diào)用Dep.notify(),notify方法是依次執(zhí)行attr.Dep數(shù)組中watch對象的update方法
3.update()是重新渲染視圖的過程,中間生成的Vnode DOM Tree,供patch使用 (利用diff算法)
四、update中的patch
patch,是將update產(chǎn)生的New Vnode節(jié)點與上一次渲染的Old Vnode進行對比的過程,最終只有對比后的差異節(jié)點才會被更新到視圖上,從而達到提高update性能的目的
hash router和history的區(qū)別:
hash模式url里面永遠帶著#號,我們在開發(fā)當中默認使用這個模式。window.location.href
如果用戶考慮url的規(guī)范那么就需要使用history模式,因為history模式?jīng)]有#號,是個正常的url適合推廣宣傳 history.pushState
功能也有區(qū)別,比如我們在開發(fā)app的時候有分享頁面,那么這個分享出去的頁面就是用vue或是react做的,
咱們把這個頁面分享到第三方的app里,有的app里面url是不允許帶有#號的,所以要將#號去除那么就要使用history模式
但是使用history模式還有一個問題就是,在訪問二級頁面的時候,做刷新操作,會出現(xiàn)404錯誤,那么就需要和后端人配合讓他配置一下apache或是nginx的url重定向,重定向到你的首頁路由上就ok啦。
偽類和偽元素
偽類的受體是文檔樹中已有的元素,而偽元素則創(chuàng)建了一個DOM外的元素
偽類用于添加元素的特殊效果,而偽元素則是添加元素的內(nèi)容
偽類使用的一個冒號,為元素使用兩個冒號
偽類更常用一些簡單的動畫或者交互的樣式,例如滑入滑出,而為偽元素更常用語字體圖標,清除浮動等
BFC
滿足下列條件之一就可以觸發(fā)BFC
1:根元素,即html元素
2:float的值不為none
3:overflow的值不為visible
4:display的值為inline-block、table-cell、table-caption
5:position的值為absolute或者fixed
CSS選擇器有哪些?哪些屬性可以繼承?CSS優(yōu)先級算法如何計算?
- id選擇器( # myid)
- 類選擇器(.myclassname)
- 標簽(元素)選擇器(div, h1, p)
- 相鄰選擇器(h1 + p)
- 子選擇器(ul > li)
- 后代選擇器(li a)
- 通配符選擇器( * )
- 屬性選擇器(a[rel = "external"])
- 偽類選擇器(a:hover, li:nth-child)
偽元素選擇器、分組選擇器。
繼承性:
可繼承的樣式:font-size, font-family, color,ul,li,dl,dt,dd;
不可繼承的樣式:border, padding, margin, width, height
優(yōu)先級(就近原則):!important > [ id > class > tag ]
!important 比內(nèi)聯(lián)優(yōu)先級高
優(yōu)先級算法計算
優(yōu)先級就近原則,同權(quán)重情況下樣式定義最近者為準
!important>id >class>tag
important比內(nèi)聯(lián)優(yōu)先級高
元素選擇符的權(quán)值:元素標簽(派生選擇器):1,class選擇符:10,id選擇符:100,內(nèi)聯(lián)樣式權(quán)值最大,為1000
!important聲明的樣式優(yōu)先級最高,如果沖突再進行計算。
如果優(yōu)先級相同,則選擇最后出現(xiàn)的樣式。
繼承得到的樣式的優(yōu)先級最低。
position
absolute
生成絕對定位的元素,相對于 static 定位以外的第一個父元素進行定位。
元素的位置通過 "left", "top", "right" 以及 "bottom" 屬性進行規(guī)定。
fixed
生成固定定位的元素,相對于瀏覽器窗口進行定位。(老IE不支持)
元素的位置通過 "left", "top", "right" 以及 "bottom" 屬性進行規(guī)定。
relative
生成相對定位的元素,相對于其正常位置進行定位,不脫離文檔流。
因此,"left:20" 會向元素的 LEFT 位置添加 20 像素。
static 默認值。沒有定位,元素出現(xiàn)在正常的文檔流中(忽略 top, bottom, left, right 或者 z-index 聲明)。
inherit 規(guī)定應該從父元素繼承 position 屬性的值。
vue和react區(qū)別
設計思想
react
1 函數(shù)式思想,all in js ,jsx語法,js操控css
2 單項數(shù)據(jù)流
3 setState重新渲染
4 每當應用的狀態(tài)被改變時,全部子組件都會重新渲染。當然,這可以通過shouldComponentUpdate這個生命周期方法來進行控制,如果為true繼續(xù)渲染、false不渲染,但Vue將此視為默認的優(yōu)化。
vue
1 響應式思想,也就是基于數(shù)據(jù)可變的。把html、js、css、組合到一起,也可以通過標簽引擎組合到一個頁面中
2 雙向綁定,每一個屬性都需要建立watch監(jiān)聽(頁面不用,涉及到組件更新的話需要)
3 Vue宣稱可以更快地計算出Virtual DOM的差異,這是由于它在渲染過程中,會跟蹤每一個組件的依賴關(guān)系,不需要重新渲染整個組件樹
兩者本質(zhì)的區(qū)別:模板和組件化的區(qū)別
Vue本質(zhì)是MVVM框架,由MVC發(fā)展而來;
React是前端組件化框架,由后端組件化發(fā)展而來;
Vue使用模板
React使用JSX
React本身就是組件化
Vue是在MVVM上擴展的
共同點:
都支持組件化,都是數(shù)據(jù)驅(qū)動視圖
ES6相關(guān)
let 聲明變量 (推薦)
特性
1、支持 塊作用域
2、不支持 JS預解析
3、不支持 重復聲明 (同域同名變量)
const 聲明常量
特性
1、let所有特性
2、聲明時必須賦值,否則報錯
3、定義常量后,再也不能更改值
解構(gòu)賦值
箭頭函數(shù)
導出語法
模板字符串(${name})
...展開運算符,react大量用到
promise
瀏覽器緩存
強緩存通過Expires和Cache-Control兩種響應頭實現(xiàn)
1、Expires
Expires是http1.0提出的一個表示資源過期時間的header,它描述的是一個絕對時間,由服務器返回。
Expires 受限于本地時間,如果修改了本地時間,可能會造成緩存失效
2、Cache-Control
Cache-Control 出現(xiàn)于 HTTP / 1.1,優(yōu)先級高于 Expires ,表示的是相對時間
Cache-Control: no-store才是真正的不緩存數(shù)據(jù)到本地
Cache-Control: no-cache代表使用協(xié)商緩存
Cache-Control: public可以被所有用戶緩存(多用戶共享),包括終端和CDN等中間代理服務器
Cache-Control: private只能被終端瀏覽器緩存(而且是私有緩存),不允許中繼緩存服務器進行緩存
當瀏覽器對某個資源的請求沒有命中強緩存,就會發(fā)一個請求到服務器,驗證協(xié)商緩存是否命中,如果協(xié)商緩存命中,請求響應返回的http狀態(tài)為304并且會顯示一個Not Modified的字符串
協(xié)商緩存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】這兩對Header來管理的
Last-Modified 表示本地文件最后修改日期,瀏覽器會在request header加上If-Modified-Since(上次返回的Last-Modified的值),詢問服務器在該日期后資源是否有更新,有更新的話就會將新的資源發(fā)送回來
但是如果在本地打開緩存文件,就會造成 Last-Modified 被修改,所以在 HTTP / 1.1 出現(xiàn)了 ETag
Max-Age相比Expires?
Expires使用的是服務器端的時間
但是有時候會有這樣一種情況-客戶端時間和服務端不同步
那這樣,可能就會出問題了,造成了瀏覽器本地的緩存無用或者一直無法過期
所以一般http1.1后不推薦使用Expires
而Max-Age使用的是客戶端本地時間的計算,因此不會有這個問題
因此推薦使用Max-Age。
注意,如果同時啟用了Cache-Control與Expires,Cache-Control優(yōu)先級高。
使用閉包的注意點
1)由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
2)閉包會在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內(nèi)部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
防抖節(jié)流(函數(shù)防抖是某一段時間內(nèi)只執(zhí)行一次,而函數(shù)節(jié)流是間隔時間執(zhí)行。)
防抖:任務頻繁觸發(fā)的情況下,只有任務觸發(fā)的間隔超過指定間隔的時候,任務才會執(zhí)行。
應用:
-輸入框聯(lián)想,以防不停的發(fā)http請求
節(jié)流:
可以將一些事件降低觸發(fā)頻率。比如懶加載時要監(jiān)聽計算滾動條的位置,但不必每次滑動都觸發(fā),可以降低計算的頻率,而不必去浪費資源;另外還有做商品預覽圖的放大鏡效果時,不必每次鼠標移動都計算位置。