知識點目錄基于 https://segmentfault.com/a/1190000018603454
根據(jù)個人理解對每個知識點附上的答案揭鳞,有錯誤歡迎大家指出。
html
1. html語義化標(biāo)簽的理解这溅、結(jié)構(gòu)化的理解
- 大部分情況,采用div+css就可以實現(xiàn)靜態(tài)頁面黄伊,但是這樣的布局會導(dǎo)致文檔結(jié)構(gòu)不夠清晰岛啸,而且不利于瀏覽器的讀取钓觉。而如果采用語義強的標(biāo)簽,比如用H系列標(biāo)簽表示標(biāo)題,strong表示強調(diào)等坚踩,這樣就能提升網(wǎng)站的可讀性议谷,便與團隊開發(fā)和維護。
- 結(jié)構(gòu)化也是為了增加代碼可讀性堕虹,提升網(wǎng)頁質(zhì)量卧晓,比如header、footer表示文檔頁眉頁腳赴捞,nav表示導(dǎo)航等逼裆。
2. 能否寫出簡潔的html結(jié)構(gòu)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>標(biāo)題</title>
</head>
<body>
內(nèi)容
</body>
</html>
3. SEO優(yōu)化
- h1標(biāo)簽頁面只能出現(xiàn)一次,權(quán)重最高
- 減少div標(biāo)簽的使用赦政,盡量使用語義化強的標(biāo)簽
- 注重meta標(biāo)簽的使用胜宇,比如name屬性設(shè)置為description、keywords等恢着,對搜索引擎的索引有幫助桐愉。
- 注重a標(biāo)簽和img標(biāo)簽的鏈接(title)和圖片說明(alt)
- 減少http請求次數(shù),合理設(shè)置http緩存(合并css掰派、js从诲、圖片等外部資源文件)
- 減少圖片數(shù)量,小圖標(biāo)可以用精靈圖的方式
- 啟用文件壓縮等
4. html5新增了哪些特性
- 增加語義標(biāo)簽
header靡羡、footer系洛、nav、section文檔中的一節(jié)略步、article頁面的獨立內(nèi)容區(qū)域描扯、aside頁面?zhèn)冗厵趦?nèi)容、detailes文檔某個細節(jié)部分趟薄、summary包含details元素的標(biāo)題绽诚、dialog對話框
- 增強表單
提供input更多輸入類型,如color杭煎、date恩够、email、number岔帽、range玫鸟、tel、week犀勒、url屎飘、search等;新的表單元素datalist(其id屬性與input的list屬性綁定贾费,實現(xiàn)選項列表輸入)钦购;新表單元素keygen、output等褂萧;新增placehoder押桃、required、pattern导犹、min唱凯、max羡忘、step、height磕昼、width卷雕、autofocus、multiple屬性票从。
- 提供audio漫雕、video標(biāo)簽
- 新增canvas容器標(biāo)簽,結(jié)合js繪制圖形峰鄙、路徑浸间、文本等。
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);
</script>
還有moveTo(x,y)線條開始坐標(biāo)吟榴、lineTo(x,y)線條結(jié)束坐標(biāo)魁蒜;
fillText(text,x,y)實心文本、strokeText(text,x,y)心文本;
createLinearGradient(x,y,x1,y1) - 創(chuàng)建線條漸變
createRadialGradient(x,y,r,x1,y1,r1) - 創(chuàng)建一個徑向/圓漸變
drawImage(image,x,y) - 將圖片放在畫布上等
- 新增API
網(wǎng)絡(luò):
檢測網(wǎng)絡(luò)狀態(tài): window.navigator.onLine
事件監(jiān)聽:online和offline 監(jiān)聽連上網(wǎng)絡(luò)和斷開網(wǎng)絡(luò)
地理定位:
獲取當(dāng)前地理信息:
window.navigator.geolocation.getCurrentPosition(
successCallback,
errorCallback,
options
)
重復(fù)獲取當(dāng)前地理信息:
window.navigator.geolocation.watchPosition(
successCallback,
errorCallback,
options
)
成功的回調(diào)參數(shù):
position.coords.latitude 緯度
position.coords.longitude經(jīng)度
web存儲:
sessionStorage(生命周期為關(guān)閉瀏覽器) 5M
localStorage(永久生效煤墙,除非手動刪除) 20M
全屏:
允許用戶自定義網(wǎng)上任一元素全屏顯示:
requestFullScreen() 開啟全屏
cancelFullScreen() 關(guān)閉全屏
文件讀取:
FileList對象梅惯,input上傳文件后返回該對象
FileReader對象:
讀取:readAsDataURL(file.files[0])
監(jiān)聽: onload
拖拽:
給元素設(shè)置draggable="true"仿野,其中img和a標(biāo)簽?zāi)J可拖拽
事件監(jiān)聽:
拖拽元素:
drag: 拖拽過程中一直調(diào)用
dragstart: 拖拽開始調(diào)用
dragleave: 鼠標(biāo)離開拖拽元素調(diào)用
dragend: 拖拽結(jié)束調(diào)用
目標(biāo)元素:
dragenter:拖拽元素進入時調(diào)用
dragover:停留在目標(biāo)元素上時調(diào)用,注意阻止瀏覽器默認行為(event.preventDefault())
drop:當(dāng)在目標(biāo)元素上松開鼠標(biāo)時調(diào)用
dragleave:當(dāng)鼠標(biāo)離開目標(biāo)元素時調(diào)用
可以通過dataTransfer拿到當(dāng)前的拖拽進來的文件列表
多媒體:
load()铣减、play()、pause()
css
1. css選擇器
- 標(biāo)簽~
- 類~
- id~
- 并集~(逗號)
- 交集~(標(biāo)簽連寫)
- 后代~(空格)
- 子~(>)
- 相鄰兄弟~(+)
- 兄弟()
- 通配符~(*)
- 屬性~([])
- 序~(:first-child脚作、:last-child葫哗、nth-child等)
- 偽類~
- 偽元素~
css3新增的屬性和選擇器:
屬性選擇器、偽類選擇器球涛、反選偽類(:not())
box-shadow劣针、border-image、
text-overflow(clip|ellipsis|string)亿扁、word-wrap捺典、border-radius、opacity从祝、
box-sizing襟己、resize、
background-size牍陌、background-origin擎浴、background-clip
transform、trasition毒涧、animation
2. 三大特性
- 繼承性(父元素設(shè)置屬性贮预,子元素默認也生效。color-|font-|text-|line-開頭的可以繼承)
- 層疊性(多個選擇器選中同一元素,修改同一屬性時仿吞。覺得如何生效需要根據(jù)優(yōu)先級判斷)
- 優(yōu)先級
3. BFC機制
- BFC(Block Formatting Context)概念
格式化上下文滑频,指一個獨立的渲染區(qū)域或者說是一個隔離的獨立容器
- 形成BFC的條件
- 浮動元素,float除none以外的值
- 定位元素茫藏,position(absolute误趴、fixed)
- display(inline-block、table-cell务傲、table-caption)
- overflow(除visible以外的值)hidden、auto枣申、scroll
- body根元素
- BFC的特性
- 是個獨立容器售葡,內(nèi)部元素不會影響外面元素
- 不被浮動元素覆蓋
- 父元素是BFC時,不會被子元素的margin擠下來
- BFC容器的高度忠藤,內(nèi)部浮動元素也參與計算(比如overflow:hidden清除浮動挟伙,可以讓內(nèi)部浮動元素也能撐開父元素高度)
4. 盒模型
將元素類比為一個盒子,有外邊距模孩、邊框尖阔、內(nèi)邊距、寬度榨咐、高度五個元素決定齊所占的元素空間大小
常見問題:
- padding內(nèi)邊距會導(dǎo)致元素的寬度和高度變化
可通過box-sizing:border-box鎖定元素寬高;
content-box 元素的寬高 = 邊框 + 內(nèi)邊距 + 內(nèi)容寬高
border-box 元素的寬高 = width/height的寬高
- margin合并現(xiàn)象(默認垂直方向的外邊距不會疊加介却,會出現(xiàn)合并,誰的邊距大就按照誰的來)块茁;
將其中一個元素放入一個BFC模式的元素內(nèi)(不推薦齿坷,會改變文檔結(jié)構(gòu));一般會給其中一個元素設(shè)置margin-bottom直接給夠距離
- margin塌陷現(xiàn)象数焊,內(nèi)部盒子的外邊距會將父盒子頂下來
利用BFC機制永淌,比如父盒子設(shè)置overflow:hidden;
- 寬度高度問題
內(nèi)容寬高 = width/height
元素寬高 = 邊框+內(nèi)邊距+width/height;設(shè)置box-sizing:border-box后值為:width/height
元素空間的寬高:外邊距+邊框+內(nèi)邊距+width/height
5.css模塊化開發(fā)(css預(yù)處理器:stylus/scss/less)
css預(yù)處理器方便開發(fā)佩耳,無需考慮瀏覽器兼容問題遂蛀,代碼模塊化、清晰簡潔
scss 是 sass3 引入新的語法干厚,其語法完全兼容 css3李滴,并且繼承了 sass 的強大功能。sass 和 scss 其實是同一種東西萍诱,我們平時都稱之為 sass悬嗓,兩者之間不同之處有以下兩點:1.文件擴展名不同(.sass/.scss);2.語法書寫方式不同,sass 是以嚴格的縮進式語法規(guī)則來書寫裕坊,不帶大括號({})和分號(;)包竹,而 scss 的語法書寫和我們的 css 語法書寫方式非常類似。
6. 屏幕適配以及頁面自適應(yīng)
- 允許網(wǎng)頁寬度自動調(diào)整
<meta name="viewport" content="width=device-width,initial-scale=1" />
- 寬度百分比
- 相對字體rem/em
- 流動布局,利用float或者display:fixed等
- 使用css media模塊
@media screen and (min-width: 768px) and (max-width: 1024px)
...
- 圖片自適應(yīng)周瞎,max-width/min-width等
7. 布局相關(guān)
- 標(biāo)準文檔流(padding+margin)+浮動+定位
- 百分比布局
- flex彈性布局
- grid柵格布局(display:grid)苗缩,使用框架中的類名來替代,本質(zhì)上還是百分比布局
JavaScript
1. 變量數(shù)據(jù)類型及檢測:基本 + 引用
基本:String声诸、Number酱讶、Boolean、Undefined彼乌、Null
引用:Object(Array泻肯、Function...)
檢測:
typeof(用于基本類型;typeof null返回object;typeof []返回object)
變量 === null ? 'null' : typeof 變量
instanceof(用于引用類型;不適用undefined和null)
(變量).constructor(不適用undefined和null)
Object.prototype.toString.call(),可以解決判斷所有類型
2. 運算符
- 算術(shù)運算符(+慰照、-灶挟、*、/毒租、%稚铣、++、--)
- 賦值運算符(=墅垮、+=惕医、-=、*=算色、/=抬伺、%=)
- 條件運算符(三元表達式)
- 邏輯運算符(!、&&(短路剃允,第一個值為false沛简,第二個值不用檢測了)、||(短路斥废,第一個值為true椒楣,第二個值不用檢測了))
- 比較運算符(雙等于、===牡肉、!=捧灰、>、<统锤、>=毛俏、<=)
- 位運算符(非~、按位與&饲窿、按位或|煌寇、異或^、左移<<逾雄、有符號右移>>阀溶、無符號右移>>>)
- 顯示類型轉(zhuǎn)換(Boolean()腻脏、Number()、String()银锻、Object()等)
- 隱示類型轉(zhuǎn)換
+運算符的一個值如果是字符串永品,它會把另一個值轉(zhuǎn)為字符串拼接
一元+,會將值試圖轉(zhuǎn)為數(shù)字击纬,如 +"5"
一元!鼎姐,會將值試圖轉(zhuǎn)為boolean,再取反
在做比較運算時更振,也會發(fā)生很多隱示轉(zhuǎn)換:
對象轉(zhuǎn)字符串再轉(zhuǎn)數(shù)字
布爾轉(zhuǎn)數(shù)字
字符串轉(zhuǎn)數(shù)字
- 條件語句(if炕桨、switch case);循環(huán)語句(for殃饿、while谋作、do while、foreach乎芳、for of、for in等)
3. 函數(shù)
函數(shù)定義:
function example(param){}
const example = function(param){}
(function (param){})()
const example = new Function('param', '')
(param) => {} 箭頭函數(shù)內(nèi)的this與外層的this一樣帖池,箭頭函數(shù)不能提升
函數(shù)調(diào)用:
函數(shù)名調(diào)用 example(param)相當(dāng)于window.example(param)
作為方法調(diào)用奈惑,比如某個對象中的行為 obj.example(param)
構(gòu)造函數(shù)調(diào)用 const exampleObj = new example(param); exampleObj.屬性/行為
作為函數(shù)方法調(diào)用函數(shù)call()、apply():
obj = example.call(obj, param1, param2)
obj = example.apply(obj, paramArray)
call和apply詳解:
在javascript中睡汹,call和apply都是為了改變某個函數(shù)運行時的上下文(context)而存在的肴甸,換句話說,就是為了改變函數(shù)體內(nèi)部this的指向囚巴。
function fruits() {}
fruits.prototype = {
color: "red",
say: function() {
console.log("My color is " + this.color);
}
}
var apple = new fruits;
apple.say(); //My color is red
banana = {
color: "yellow"
}
apple.say.call(banana); //My color is yellow
apple.say.apply(banana); //My color is yellow
所以原在,可以看出call和apply是為了動態(tài)改變this而出現(xiàn)的,當(dāng)一個object沒有某個方法(本例子中banana沒有say方法)彤叉,
但是其他的有(本例子中apple有say方法)庶柿,我們可以借助call或apply用其它對象的方法來操作。
二者區(qū)別:
func.call(this, arg1, arg2); 若干個參數(shù)
func.apply(this, [arg1, arg2]); 數(shù)組參數(shù)
常用實例:
數(shù)組追加:
var array1 = [12 , "foo" , {name:"Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
// array1 值為 [12 , "foo" , {name:"Joe"} , -2458 , "Doe" , 555 , 100]
獲取數(shù)組中的最大值和最小值:
var numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math, 5, 458, 120, -215); //458
// number 本身沒有 max 方法秽浇,但是 Math 有浮庐,我們就可以借助 call 或者 apply 使用其方法。
驗證是否是數(shù)組(前提是toString()方法沒有被重寫過):
functionisArray(obj){
return Object.prototype.toString.call(obj) === '[object Array]' ;
}
真?zhèn)螖?shù)組轉(zhuǎn)換:
真轉(zhuǎn)偽:[].push.apply(obj, arr);
偽轉(zhuǎn)真:[].slice.call(obj);
bind 是返回對應(yīng)函數(shù)柬焕,便于稍后調(diào)用审残;apply 、call 則是立即調(diào)用
- 實參形參傳值問題
基本類型斑举,按值傳遞(函數(shù)內(nèi)部修改形參值搅轿,不會影響外部實參值)
引用類型,按對象共享傳遞
var obj = {};
function f(o) {
o.name = 'li';
}
f(obj);
console.log(obj.name); //li 被修改了
var obj = {};
function f(o) {
o = [];
}
f(obj);
console.log(obj); //{} 沒有修改
調(diào)用函數(shù)傳參時富玷,函數(shù)接受對象實參引用的副本(既不是按值傳遞的對象副本璧坟,也不是按引用傳遞的隱式引用)既穆。
它和按引用傳遞的不同在于:在共享傳遞中對函數(shù)形參的賦值,不會影響實參的值沸柔。如下面例子中循衰,不可以通過修改形參o的值,來修改obj的值褐澎。
也就是說不可以改變引用類型的指針会钝,只可以改變這個對象的屬性
4. 字符串、數(shù)組工三、對象常用API
- 數(shù)組方法
concat()拼接數(shù)組迁酸,參數(shù)是任意個值或者數(shù)組,返回新數(shù)組俭正,不影響原數(shù)組
join()將數(shù)組的值用指定分隔符轉(zhuǎn)成字符串奸鬓,不傳參默認為逗號,返回新值,不影響原值
pop()刪除并返回數(shù)組最后一個元素
push()向數(shù)組末尾添加一個或多個元素掸读,返回數(shù)組新長度
shift()刪除并返回數(shù)組第一個元素
unshift()想數(shù)組開頭添加一個或多個元素串远,返回數(shù)組新長度
slice(start,end)包含頭不包含尾,返回新值對原值沒有影響
splice(index,howmany,item1...,itemX)
可用于替換儿惫,刪除澡罚,添加;
howmany表示要刪除的個數(shù),返回被刪除的值組成的數(shù)組肾请,原數(shù)組被修改
sort()對數(shù)組元素排序,修改原值
reverse()點到數(shù)組中元素的順序,修改原值
every()是對數(shù)組中的每一項運行給定函數(shù)留搔,如果每一項都返回true,則返回true
some()是對數(shù)組中的每一項運行給定函數(shù)铛铁,如果對任一項返回true隔显,則返回true
filter()是對數(shù)組中的每一項運行給定函數(shù),返回該函數(shù)返回true的項組成數(shù)組
map()是對數(shù)組中的每一項運行給定函數(shù)饵逐,返回每次函數(shù)調(diào)用的結(jié)果組成數(shù)組
reduce()從數(shù)組元素中計算出一個值
arr.indexOf('')查找數(shù)組括眠,判斷數(shù)組中是否含有某一項
- 字符串
三個字符方法:
charAt()返回給定位置的字符
charCodeAt()返回給定位置的字符編碼
str[index]直接用方括號加索引也能返回指定位置的字符,IE7及更早版本不支持
操作字符串方法:
concat()用于拼接字符串梳毙,可傳任意個參數(shù)
slice(start,end)包含頭不包含尾哺窄,返回新值對原值沒有影響
substring(start,end)包含頭不包含尾,返回新值對原值沒有影響
substr(start,num)第二個參數(shù)為個數(shù)账锹,返回新值對原值沒有影響
字符串位置方法:
indexOf()從前往后找萌业、lastIndexOf()從后往前找
大小寫:
toLowerCase()、toLocaleLowerCase()奸柬、toUpperCase()生年、toLocaleUpperCase()
都是返回新值對原值沒有影響
字符串的模式匹配方法:
match()參數(shù)為正則表達式或者RegExp對象,返回匹配的數(shù)組
search()返回字符串中第一個匹配項的索引廓奕,如果沒找到就返回-1
replace(egexp/substr, replacement/function)抱婉,返回新值對原值沒有影響
split()基于分隔符分割字符串档叔,返回新數(shù)組對原值沒有影響
trim()刪除字符串前后所有空格,返回新值對原值沒有影響
5. 正則表達式
格式:/正則表達式主體/修飾符(可選)
\d: 0-9任意一個數(shù)字
\w: 數(shù)字蒸绩、字母衙四、下劃線 0-9 a-z A-Z _
\s: 空格或者空白
(): 分組
[a-z]: 區(qū)間內(nèi)任意一個
*: 0到多個
+: 1到多個
{n}: 正好n次
{n,m}: n-m次
比如手機:/1[34578]\d{9}/
6. 作用域、作用域鏈患亿、閉包
- 作用域
全局作用域传蹈、函數(shù)作用域
ES6引入let和const關(guān)鍵字,隨即帶來塊級作用域的概念
- 作用域鏈
對象有一個內(nèi)部屬性[[Scope]]步藕,該屬性包含了函數(shù)被創(chuàng)建的作用域中對象的集合惦界,這個集合被稱為函數(shù)的作用域鏈。
js解析某個變量時咙冗,會從代碼嵌套的最內(nèi)層開始沾歪,如果沒找到继薛,會順著作用域鏈向上查找慨削。
- 閉包
函數(shù)內(nèi)部返回一個函數(shù)
對外部暴露指定行為,但還是能用到自己作用域內(nèi)的變量
function greet(){
name = 'Alan';
return function() {
console.log('Hi ' + name);
}
}
greet()();
私有作用域
(function () {
// private scope
)()
模塊模式
var Module = (function () {
function _privateMethod() {}
return {
publicMethod: function() {
// can call privateMethod();
}
}
})()
7. 構(gòu)造函數(shù)殴蓬、原型立润、原型鏈确镊、繼承
- 構(gòu)造函數(shù)、原型和實例之間的關(guān)系
構(gòu)造函數(shù)的prototype指向一個原型對象范删,
原型對象的constructor指回構(gòu)造函數(shù),
實例的內(nèi)部指針__proto__指向原型對象拷肌。
通過調(diào)用構(gòu)造函數(shù)產(chǎn)生的實例到旦,都有一個內(nèi)部屬性,指向了原型對象巨缘。所以實例能夠訪問原型對象上的所有屬性和方法
例子:
function Dog (name) {
this.name = name;
}
Dog.prototype.speak = function () {
alert('wang');
}
var doggie = new Dog('jiwawa');
doggie.speak(); //wang
Dog.prototype.constructor == Dog //true
graph LR
C[實例] --> B
A[構(gòu)造函數(shù)Dog] --> B[Dog的原型對象]
B --> A
- 原型鏈添忘、繼承
//定義一個 Animal 構(gòu)造函數(shù),作為 Dog 的父類
function Animal () {
this.superType = 'Animal';
}
Animal.prototype.superSpeak = function () {
alert(this.superType);
}
function Dog (name) {
this.name = name;
}
//改變Dog的prototype指針若锁,指向一個 Animal 實例
Dog.prototype = new Animal();
Dog.prototype.speak = function () {
alert(this.type);
}
var doggie = new Dog('jiwawa');
doggie.superSpeak(); //Animal
如果將Dog的prototype指針指向另一個Animal的實例搁骑,那么Dog的實例就能調(diào)用Animal的屬性和方法。
8. 函數(shù)上下文(this指向)
規(guī)律一:函數(shù)名加圓括號直接調(diào)用又固,函數(shù)上下文是 window 對象仲器。
規(guī)律二:函數(shù)如果作為一個對象的方法,對象使用點方法進行調(diào)用仰冠,那么函數(shù)的上下文就是這個對象乏冀。
規(guī)律三:函數(shù)是事件處理函數(shù),那么函數(shù)的上下文就是觸發(fā)這個事件的對象洋只。
規(guī)律四:函數(shù)被定時器調(diào)用時辆沦,上下文是 window 對象昼捍。
規(guī)律五:數(shù)組中存放的函數(shù),被數(shù)組索引調(diào)用肢扯,函數(shù)上下文就是這個數(shù)組妒茬。
9. js的運行機制、事件隊列和循環(huán)
JS單線程(主線程)
↓
單線程導(dǎo)致任務(wù)需要排隊蔚晨,如果前一個任務(wù)耗時很長乍钻,后面的就一直等著。
如果排隊是因為計算了大蛛株,CPU忙不過來团赁,倒也算了。
很多時候沒事因為IO設(shè)備慢(比如Ajax操作從網(wǎng)絡(luò)讀取數(shù)據(jù))
↓
同步任務(wù)和異步任務(wù)
同步:在主線程上排隊執(zhí)行的任務(wù)谨履,前一個完成欢摄,才執(zhí)行后一個。
異步:不進入主線程笋粟,而進入“任務(wù)隊列”怀挠,只有“任務(wù)隊列”通知主線程,某個異步任務(wù)可以執(zhí)行了害捕,該任務(wù)才會進入主線程執(zhí)行绿淋。
只要主線程空了,就會去讀取"任務(wù)隊列"尝盼,這就是JavaScript的運行機制吞滞。這個過程會不斷重復(fù)
↓
"任務(wù)隊列"是一個事件(消息)的隊列,IO設(shè)備完成一項任務(wù)盾沫,就在"任務(wù)隊列"中添加一個事件裁赠,表示相關(guān)的異步任務(wù)可以進入"執(zhí)行棧"了。主線程讀取"任務(wù)隊列"赴精,就是讀取里面有哪些事件佩捞。
"任務(wù)隊列"中的事件,除了IO設(shè)備的事件以外蕾哟,還包括一些用戶產(chǎn)生的事件(比如鼠標(biāo)點擊一忱、頁面滾動等等)。只要指定過回調(diào)函數(shù)谭确,這些事件發(fā)生時就會進入"任務(wù)隊列"帘营,等待主線程讀取。
所謂"回調(diào)函數(shù)"(callback)琼富,就是那些會被主線程掛起來的代碼仪吧。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開始執(zhí)行異步任務(wù)鞠眉,就是執(zhí)行對應(yīng)的回調(diào)函數(shù)薯鼠。
主線程的讀取過程基本上是自動的择诈,只要執(zhí)行棧一清空,"任務(wù)隊列"上第一位的事件就自動進入主線程出皇。但是羞芍,由于"定時器"功能,主線程首先要檢查一下執(zhí)行時間郊艘,某些事件只有到了規(guī)定的時間荷科,才能返回主線程。
↓
主線程從"任務(wù)隊列"中讀取事件纱注,這個過程是循環(huán)不斷的畏浆,所以整個的這種運行機制又稱為Event Loop(事件循環(huán))。
執(zhí)行棧中的代碼(同步任務(wù))狞贱,總是在讀取"任務(wù)隊列"(異步任務(wù))之前執(zhí)行刻获。
10. Ajax(Asynchronous JavaScript and XML)原理
Ajax 是一種在無需重新加載整個網(wǎng)頁的情況下,能夠更新部分網(wǎng)頁的技術(shù)瞎嬉。
var xmlHttp;
if (window.XMLHttpRequest) {// IE7及以上
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
}
xmlHttp.open('GET/POST', url, true/false);
// 如果是post蝎毡,需要設(shè)置請求頭
xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlHttp.send(); // 如果是post,需要傳參數(shù)氧枣,參數(shù)為空就傳null;
xmlHttp.onreadystatechagne = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status >= 200 && xmlHttp.status < 300 || xmlHttp.status == 304) {
// 成功回調(diào)函數(shù)...
} else {
// 失敗回調(diào)函數(shù)...
}
}
};
相關(guān)知識點:
GET 更簡單更快沐兵,無法發(fā)送大數(shù)據(jù),無法緩存
POST 更大更穩(wěn)定便监,可發(fā)大數(shù)據(jù)扎谎,可緩存
readyState(0: 請求未初始化
1: 服務(wù)器連接已建立
2: 請求已接收
3: 請求處理中
4: 請求已完成,且響應(yīng)已就緒)
status(1字頭:消息,代表請求已被接受烧董,需要繼續(xù)處理簿透;
2字頭:成功;
3字頭:重定向解藻;
4字頭:請求錯誤;
5葡盗、6字頭:服務(wù)器錯誤)
常見:200成功螟左、304緩存、404未找到頁面觅够、500服務(wù)器錯誤
11. Axios原理
普通使用:
import axios from 'axios'
axios.get/post(url, params).then(function(){}).catch(function(){})
自定義axios常見使用方式:
let myAxios = axios.create({
baseURL: '',
timeout: 30000,
headers: {},
...
})
// 請求攔截器
myAxios.interceptors.request.use(
function (config) {
// 發(fā)送請求之前做些什么胶背,比如token
if (store.state.Token) {
config.headers.Authorization = '前綴' + store.state.Token
}
reutrn config
},
function (error) {
// 對請求錯誤,做些什么
return Promise.reject(error)
}
)
// 響應(yīng)攔截器
myAxios.interceptors.response.use(
function (response) {
// 對響應(yīng)數(shù)據(jù)做點什么
return response.data
},
function (error) {
// 對響應(yīng)錯誤做點什么, 比如后臺返回token失效的狀態(tài)碼喘先,就需要跳轉(zhuǎn)login
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = '請求出錯'
break
case 401:
alert('token失效钳吟,重新登錄')
store.commit('loginOut')
setTimeout(() => {
window.location.reload()
}, 1000)
return
}
} else {
error.message = '連接服務(wù)器失敗'
}
alert(error.message)
return Promise.reject(error.response)
}
)
12. 異步編程
- 回調(diào)函數(shù)
- 事件監(jiān)聽
- ES6/Promise對象(避免層層嵌套的異步回調(diào),代碼更清晰)
- ES6/Generator函數(shù)
- ES7/async和await
瀏覽器
1. 內(nèi)核
Trident(IE)窘拯、Gecko9(火狐)红且、Blink(Chrome坝茎、Opera)、Webkit(Safari)
2. 功能模塊
HTML解釋器
CSS解釋器
圖層布局計算模塊:布局計算每個對象的精確位置和大小
視圖繪制模塊:進行具體節(jié)點的圖像繪制暇番,將像素渲染到屏幕上
JavaScript引擎:編譯執(zhí)行JS代碼
3. 運行機制
運行機制:
瀏覽器使用http/https向服務(wù)的請求頁面
↓
解析HTML嗤放,構(gòu)建DOM樹
↓
計算DOM樹上的CSS
↓
(排版)根據(jù)CSS屬性渲染元素,得到內(nèi)存中的位圖
↓
(可選步驟)對位圖進行合成壁酬,提升后續(xù)繪制速度
↓
繪制到界面上
4. 渲染原理
解析HTML次酌,生成DOM樹(DOM)
解析CSS,生成CSSOM樹(CSSOM)
將DOM和CSSOM合并舆乔,生成渲染樹(Render-Tree)
計算渲染樹的布局(Layout)
將布局渲染到屏幕上(Paint)
5. 瀏覽器交互:BOM和DOM相關(guān)webApi岳服、監(jiān)聽事件
JavaScript分三個部分:
ECMAScript標(biāo)準 --- 基本語法
DOM --- 文檔對象模型,操作頁面元素的
BOM --- 瀏覽器對象模型希俩,操作瀏覽器的
瀏覽器頂級對象: window
頁面頂級對象: document
頁面中所有內(nèi)容都屬于瀏覽器
- BOM(Browser Object Model)瀏覽器對象模型
BOM是獨立于內(nèi)容的吊宋、可以與瀏覽器窗口進行互動的對象結(jié)構(gòu),其由多個對象組成斜纪,其中代表瀏覽器窗口的Window對象是其頂層對象贫母。
可刷新瀏覽器、后退盒刚、前進腺劣、在瀏覽器中輸入URL等。
alert()因块、prompt()橘原、confirm()
onload()、onunload()
setTimeout()涡上、clearTimeout()趾断、setInterval()、clearInterval()
loaction吩愧、history芋酌、navigator
- DOM(Document Object Model)文檔對象模型
document.
getElementById()
getElementsByTagName()
getElementsByName()
getElementsByClassName()
querySelector()
createElement()
appendChild()
- 監(jiān)聽事件
addEventListener("事件名","事件處理函數(shù)","布爾值false冒泡,true捕獲")
removeEventListener("事件名","事件處理函數(shù)","布爾值")
preventDefault()阻止默認事件
stopPropagation()阻止事件冒泡
其他常用事件:
onclick、ondbclick雁佳、
onmousedown脐帝、onmouseup、onmouseout糖权、onmousemove堵腹、onmouseover
- 事件代理(事件委托)
原理:利用事件冒泡,只指定一個事件處理程序星澳,就可以管理某一類型的所有事件
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(target.innerHTML);
}
}
}
6. 緩存機制
強緩存:用戶發(fā)送的請求疚顷,直接從客戶端緩存中獲取,不發(fā)送請求到服務(wù)器,不與服務(wù)器發(fā)生交互行為腿堤。
協(xié)商緩存:用戶發(fā)送的請求阀坏,發(fā)送到服務(wù)器后,由服務(wù)器判定是否從緩存中獲取資源释液。
兩者共同點:客戶端獲得的數(shù)據(jù)最后都是從客戶端緩存中獲得全释。
兩者的區(qū)別:從名字就可以看出,強緩存不與服務(wù)器交互误债,而協(xié)商緩存則需要與服務(wù)器交互浸船。
7. 跨域
為什么會跨域:瀏覽器的同源策略(阻止不同協(xié)議或者域名或者端口的請求)
解決方法:
JSONP(只能發(fā)GET請求)
空iframe加form
CORS(跨域資源共享):響應(yīng)頭設(shè)置Access-Control-Allow-Origin等...
代理
...
關(guān)于網(wǎng)絡(luò)協(xié)議
1. HTTP協(xié)議
HTTP(Hyper Text Transfer Protocol)超文本傳輸協(xié)議:
基于TCP/IP通信協(xié)議傳遞數(shù)據(jù),用于從萬維網(wǎng)服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議
主要特點:
簡單快速寝蹈、靈活李命、無連接(完成請求就斷開鏈接)、無狀態(tài)箫老、支持B/S C/S
- URL
HTTP使用統(tǒng)一資源標(biāo)識符URI來傳輸數(shù)據(jù)和建立連接封字,統(tǒng)一資源定位符URL是URI的一種特殊類型
URL:協(xié)議+域名+端口+虛擬目錄+文件名+錨(#)+參數(shù)(?)
- Request
請求行(請求方法 URL 協(xié)議版本)
請求頭(頭部字段名 值...)
空行(一定有一個空行)請求數(shù)據(jù)
請求數(shù)據(jù)
- Response
狀態(tài)行(協(xié)議版本 狀態(tài)碼 狀態(tài)消息)
消息報頭
空行
響應(yīng)正文(服務(wù)器返回給客戶端的文本信息)
- 狀態(tài)碼
1xx:指示信息--表示請求已接收,繼續(xù)處理
2xx:成功--表示請求已被成功接收耍鬓、理解阔籽、接受
3xx:重定向--要完成請求必須進行更進一步的操作
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現(xiàn)
5xx:服務(wù)器端錯誤--服務(wù)器未能實現(xiàn)合法的請求
常見:
200 OK:客戶端請求成功
400 Bad Request:客戶端請求有語法錯誤,不能被服務(wù)器所理解
401 Unauthorized:請求未經(jīng)授權(quán)牲蜀,這個狀態(tài)代碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden:服務(wù)器收到請求笆制,但是拒絕提供服務(wù)
404 Not Found:請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error:服務(wù)器發(fā)生不可預(yù)期的錯誤
503 Server Unavailable:服務(wù)器當(dāng)前不能處理客戶端的請求涣达,一段時間后可能恢復(fù)正常
- 請求方法
GET在辆、HEAD、POST度苔、PUT匆篓、DELETE、CONNECT寇窑、OPTIONS鸦概、TRACE
- HTTP工作原理
建立TCP連接(三次握手),客戶端連接服務(wù)器
↓
發(fā)送HTTP請求
↓
服務(wù)器接受請求甩骏,返回HTTP響應(yīng)
↓
釋放TCP連接
↓
瀏覽器解析HTML內(nèi)容
- GET和POST區(qū)別
GET: 請求數(shù)據(jù)附在URL后完残,地址欄可見
POST: 請求數(shù)據(jù)包在請求體中
GET: 長度有限(2083字節(jié))
POST: 理論上不限制大小,服務(wù)器常會對POST數(shù)據(jù)大小進行限制
GET: 數(shù)據(jù)明文横漏,不安全
POST: 安全
2. cookie、session熟掂、token缎浇、localStorage、sessionStorage
- Cookie
客戶端緩存技術(shù)
瀏覽器的一種數(shù)據(jù)存儲功能赴肚,由服務(wù)器生成素跺,發(fā)送給瀏覽器二蓝,以鍵值方式存儲,下次請求指厌,會把cookie發(fā)送給服務(wù)器刊愚,過期時長由expire決定
- Session
會話緩存技術(shù)
類似客戶端的身份標(biāo)識,由服務(wù)器生成踩验,保存在服務(wù)器端鸥诽,以鍵值方式存儲,默認30分鐘過期
客戶端每次像服務(wù)器發(fā)送請求箕憾,都帶上身份標(biāo)識牡借,服務(wù)器就知道請求來自誰∠欤客戶端常用cookie方式保存標(biāo)識
- Token
用戶登錄成功钠龙,服務(wù)器生成Token返回給客戶端
客戶端保存Token
客戶端每次請求攜帶Token
服務(wù)器校驗Token
- localStorage
生命周期永久,除非手動清楚御铃,存放大小一般5MB碴里,存在客戶端
- sessionStorage
當(dāng)前會話有效,關(guān)閉瀏覽器清楚上真,存放大小5MBD咬腋,存在客戶端
關(guān)于ES6語法
- 變量聲明 let/const
變量名不自動提示,提供塊級作用域
- 箭頭函數(shù)
() => {}
箭頭函數(shù)中沒有this谷羞,如果在箭頭函數(shù)內(nèi)使用this帝火,該this是外層的this
- 模板字符串
使用``將字符串包裹,在其中可以使用${}來包裹一個變量或表達式
- 解析結(jié)構(gòu)
數(shù)組以序列號對應(yīng)湃缎,對象根據(jù)屬性名對應(yīng)
eg:
// es5
var loading = props.loading;
var clicked = props.clicked;
// es6
const { loading, clicked } = props;
// es6
const arr = [1, 2, 3];
const [a, b, c] = arr;
// es5
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
- 函數(shù)默認參數(shù)
// es5
function add(x, y) {
var x = x || 20;
var y = y || 30;
return x + y;
}
console.log(add());
// es6
function add(x = 20, y = 30) {
return x + y;
}
console.log(add());
- 展開運算符
使用...可以將數(shù)組或者對象進行展開
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 10, 20, 30];
// 這樣犀填,arr2 就變成了[1, 2, 3, 10, 20, 30];
const obj1 = {
a: 1,
b: 2,
c: 3
}
const obj2 = {
...obj1,
d: 4,
e: 5,
f: 6
}
// 結(jié)果類似于 const obj2 = Object.assign({}, obj1, {d: 4})
- 對象字面量與class
當(dāng)屬性與值同名時,可簡寫
const person = {
name,
age
}
// ES5
// 構(gòu)造函數(shù)
function Person(name, age) {
this.name = name;
this.age = age;
}
// 原型方法
Person.prototype.getName = function() {
return this.name
}
// ES6
class Person {
constructor(name, age) { // 構(gòu)造函數(shù)
this.name = name;
this.age = age;
}
getName() { // 原型方法
return this.name
}
}
extends繼承關(guān)鍵字嗓违、super()
- Promise
解決異步回調(diào)地獄問題
promise.then(function(value) {
// success 成功回調(diào)
}, function(error) {
// failure 失敗回調(diào)
});
then方法返回一個新的Promise實例九巡,因此支持鏈式寫法,后面的then會等待前面then返回的Promise對象狀態(tài)發(fā)生變化蹂季,然后決定調(diào)用resolve還是reject冕广。
.catch()
.finally() ES2018引入, 不管promise最后狀態(tài),都會執(zhí)行
.all()將多個Promise實例包裝成一個新的Promise實例偿洁,只有子實例狀態(tài)都變?yōu)閒ulfilled撒汉,包裝實例才變?yōu)閒ulfilled,如果其中一個是rejected涕滋,那么包裝也是rejected睬辐。
.race()同all()方法,相當(dāng)于或操作,只要有一個實例狀態(tài)改變溯饵,包裝實例就會跟著改變
.resolve()將現(xiàn)有對象轉(zhuǎn)為Promise對象
.reject()返回一個狀態(tài)為rejected的Promise實例
- Modules
- Symbol(表示獨一無二的值)
- Set和Map
Set類似于數(shù)組侵俗,但其成員的值都是唯一的,沒有重復(fù)的值
const s = new Set()
const s1 = new Set([1,2,3,2,3])
[...s]
add(value):添加某個值丰刊,返回 Set 結(jié)構(gòu)本身隘谣。
delete(value):刪除某個值,返回一個布爾值啄巧,表示刪除是否成功寻歧。
has(value):返回一個布爾值,表示該值是否為Set的成員棵帽。
clear():清除所有成員熄求,沒有返回值。
類似于對象逗概,也是鍵值對的集合弟晚,但是鍵不限于字符串,各種類型都可以當(dāng)作鍵逾苫。
const map = new Map()
map.set(鍵,值)
map.get(鍵)
map.has(鍵)
map.delete(鍵)
map.clear()
map.size
遍歷Set和Map:
keys():返回鍵名的遍歷器卿城。
values():返回鍵值的遍歷器。
entries():返回所有成員的遍歷器铅搓。
forEach():遍歷 Map 的所有成員
由于 Set 結(jié)構(gòu)沒有鍵名瑟押,只有鍵值(或者說鍵名和鍵值是同一個值),所以keys方法和values方法的行為完全一致
- Proxy
在目標(biāo)對象之前架設(shè)一層“攔截”星掰,外界訪問該對象多望,都必須先通過這層攔截
var proxy = new Proxy(target, handler)
eg:
var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});
get(target, propKey, receiver):
攔截對象屬性的讀取,比如proxy.foo和proxy['foo']氢烘。
set(target, propKey, value, receiver):
攔截對象屬性的設(shè)置怀偷,比如proxy.foo =v或proxy['foo']=v,返回一個布爾值播玖。
has(target, propKey):
攔截propKey in proxy的操作椎工,返回一個布爾值
...
- Iterator和for...of循環(huán)
Iterator作用:
1. 為各種數(shù)據(jù)結(jié)構(gòu),提供一個統(tǒng)一的訪問接口
2. 使數(shù)據(jù)結(jié)構(gòu)的成員能夠按某種次序排列
3. 創(chuàng)造了一種新的遍歷命令for...of
遍歷器原理:創(chuàng)建一個指針指向數(shù)據(jù)結(jié)構(gòu)(Array/Set/Map/String/TypedArry/arguments/NodeList)的初始位置蜀踏,
第一次調(diào)用指針對象的next方法维蒙,將指針指向第一個成員,第二次next指向第二個果覆,以此類推颅痊,直到結(jié)束位置。
for(let val of 數(shù)據(jù)結(jié)構(gòu)){}
- export 和 export default
export與export default均可用于導(dǎo)出常量局待、函數(shù)斑响、文件吗讶、模塊等
在一個文件或模塊中,export恋捆、import可以有多個,export default僅有一個
通過export方式導(dǎo)出重绷,在導(dǎo)入時要加{ }沸停,export default則不需要
export能直接導(dǎo)出變量表達式,export default不行
Vue
1. 指令
v-text:綁定元素的文本內(nèi)容 <span v-text="txt"></span>
v-html:綁定元素的innerHTML <div v-html="html"></div>
v-show:顯示與隱藏昭卓,切換元素的display CSS屬性
v-if:Dom元素的銷毀和重建
v-for
v-on:綁定事件監(jiān)聽器愤钾,縮寫@;使用:v-on:click="handleClick()"
修飾符:
.stop - 調(diào)用 event.stopPropagation()候醒。
.prevent - 調(diào)用 event.preventDefault()能颁。
.capture - 添加事件偵聽器時使用 capture 模式。
.self - 只當(dāng)事件是從偵聽器綁定的元素本身觸發(fā)時才觸發(fā)回調(diào)倒淫。
.{keyCode | keyAlias} - 只當(dāng)事件是從特定鍵觸發(fā)時才觸發(fā)回調(diào)伙菊。比如 @click.enter="handleEnter"
.native - 監(jiān)聽組件根元素的原生事件。
.once - 只觸發(fā)一次回調(diào)敌土。
.left - (2.2.0) 只當(dāng)點擊鼠標(biāo)左鍵時觸發(fā)镜硕。
.right - (2.2.0) 只當(dāng)點擊鼠標(biāo)右鍵時觸發(fā)。
.middle - (2.2.0) 只當(dāng)點擊鼠標(biāo)中鍵時觸發(fā)返干。
.passive - (2.3.0) 以 { passive: true } 模式添加偵聽器
v-bind:動態(tài)綁定一個或多個特性或組件prop到表達式兴枯,縮寫":"; 比如 :class="{}"
修飾符:
.prop - 被用于綁定 DOM 屬性 (property)。(差別在哪里矩欠?)
.camel - (2.1.0+) 將 kebab-case 特性名轉(zhuǎn)換為 camelCase. (從 2.1.0 開始支持)
.sync (2.3.0+) 語法糖财剖,會擴展成一個更新父組件綁定值的 v-on 偵聽器。
v-model:數(shù)據(jù)雙向綁定
修飾符:
.lazy - 取代 input 監(jiān)聽 change 事件
.number - 輸入字符串轉(zhuǎn)為有效的數(shù)字
.trim - 輸入首尾空格過濾
v-slot:用于<template>癌淮,縮寫#
v-pre:跳過這個元素和其子元素的編譯過程
v-cloak:與CSS規(guī)則[v-cloak]{display:none}一起使用
v-once:只渲染元素和組件一次躺坟。<span v-once>This will never change: {{msg}}</span>
2. 實例的屬性和方法
- 屬性
常用:
vm.$refs:返回Object,獲取注冊過ref特性的所有DOM元素和組件實例
其他:
vm.$data:Object该默,訪問Vue實例的data屬性
vm.$props:Object瞳氓,訪問Vue實例的props屬性
vm.$el:Element,當(dāng)前組件的根DOM元素
vm.$options:Object栓袖,訪問Vue的初始化選項
vm.$parent:獲取父實例
vm.$root:當(dāng)前組件樹的根實例
vm.$children
vm.$slots:訪問具名插槽的內(nèi)容
vm.$scopedSlots:訪問作用域插槽的內(nèi)容
vm.$isServer
vm.$attrs
vm.$listeners
- 方法
常用:
vm.$emit(eventName,[...args]):觸發(fā)當(dāng)前實例上的事件匣摘,常用于父子組件通信
vm.$watch:觀察 Vue 實例變化的一個表達式或計算屬性函數(shù)
vm.$watch('a.b.c', function (newVal, oldVal) {
// 做點什么
})
vm.$set(target,key,value)
其他:
vm.$delete(target,key)
vm.$on(event,callback):監(jiān)聽當(dāng)前實例上的自定義事件
vm.$once(event,callback):監(jiān)聽自定義事件,只觸發(fā)一次裹刮,觸發(fā)后自動移除監(jiān)聽器
vm.$off([event,callback]):移除自定義事件
vm.$mount([elementOrSelector]):可用于給vue實例手動掛載dom元素
vm.$forceUpdate():迫使vue實例重新渲染
vm.$nextTick([callback]):將回調(diào)延遲到下次DOM更新循環(huán)之后執(zhí)行音榜。在修改數(shù)據(jù)之后立即使用它,然后等待 DOM 更新
vm.$destory():完全銷毀一個實例捧弃。清理它與其它實例的連接赠叼,解綁它的全部指令及事件監(jiān)聽器
3. 生命周期
beforeCreate 實例初始化之后調(diào)用
created 實例創(chuàng)建完成后被立即調(diào)用
beforeMount 掛載開始之前被調(diào)用
mounted 掛載到實例上去之后調(diào)用該鉤子
beforeUpdate 數(shù)據(jù)更新時調(diào)用擦囊,發(fā)生在虛擬 DOM 打補丁之前
updated 由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補丁,在這之后會調(diào)用該鉤子
activated keep-alive組件激活時調(diào)用
deactivated keep-alive組件停用時調(diào)用
beforeDestory 實例銷毀之前調(diào)用
destoryed 實例銷毀后調(diào)用
errorCaptured 當(dāng)捕獲一個來自子孫組件的錯誤時被調(diào)用
4. 組件基礎(chǔ)
- 組件注冊
全局注冊:
Vue.component('name', {
data () {
return {
...
}
},
template: `<button>BTN</button>`
...
})
局部注冊:
var componentA = {}
var componentB = {}
var componentC = {}
new Vue({
el: '#app',
components: {
componentA,
componentB
}
})
5. 組件通信
- 父子
父給子傳值:
直接以屬性的方式嘴办,如果是動態(tài)值可以用v-bind瞬场,子組件通過props接受值
子給父傳值:
通過自定義事件。
子組件通過$emit('faterEvent', ...params)觸發(fā)父組件的自定義事件涧郊,父組件自定義事件觸發(fā)一個自定義方法贯被,其參數(shù)就是子組件傳過來的值。
- 兄弟
可借助同一個父組件通信
- 跨級
vuex
6. 插槽slot
- 具名插槽
定義:
<slot name="header"></slot>
調(diào)用:
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
- 作用域插槽
讓插槽內(nèi)容能夠訪問子組件中才有的數(shù)據(jù)
定義:
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
調(diào)用:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
7. vue-router
HTML:
入口(聲明式): <router-link to="/index"></router-link>
出口: <router-view></router-view>
JavaScript:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
// 定義路由
const routes=[
{path: '/index', component: ()=>require('../index')}
]
// 創(chuàng)建router實例并配置路由
const router = new Router({
routes
})
// 根實例配置router
const app = new Vue({
router
})
可以在任何組件內(nèi)通過this.$router訪問路由器妆艘,通過this.$route訪問當(dāng)前路由彤灶。
- 動態(tài)路由匹配
eg: 將不同id的用戶都指向User組件
const router = new Router({
routes: [
// 動態(tài)路徑參數(shù),以冒號開頭
{path: '/user/:id', component: User}
]
})
多次路由如果渲染同個組件批旺,組件會被復(fù)用幌陕,所以生命周期鉤子不會再調(diào)用,可以使用watch監(jiān)聽$route對象汽煮。
watch: {
'$route': (to, from) {}
}
通配符(*):
path: '*'
path: 'user-*'
如果使用通配符搏熄,$route.params會自動添加一個名為pathMatch參數(shù)
// 給出一個路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 給出一個路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'
- 編程式導(dǎo)航
Vue實例內(nèi)部使用this.$router訪問
router.push(location, onComplete?, onAbort?)
eg:
// 字符串
router.push('home')
// 對象
router.push({ path: 'home' })
// 命名的路由,如果提供了path,params會被忽略
router.push({ name: 'user', params: { userId: '123' }})
// 帶查詢參數(shù)逗物,變成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
router.replace(location, onComplete?, onAbort?)
router.go(n): 向前或后退多少步
- 導(dǎo)航守衛(wèi)
全局前置守衛(wèi):
const router = new Router({ ... })
router.beforeEach((to, from, next) => {
// 確保調(diào)用next方法搬卒,否則鉤子不會被resolved
// next() 進行下一個鉤子
// next(false) 中斷當(dāng)前的導(dǎo)航
// next('/')或者next({path: '/'}) 中斷當(dāng)前導(dǎo)航,跳轉(zhuǎn)到新導(dǎo)航
// next(error) 終止導(dǎo)航翎卓,并觸發(fā)router.onError()的回調(diào)
})
全局解析守衛(wèi):
router.beforeResolve與上面的前置守衛(wèi)類似
區(qū)別是在導(dǎo)航被確認之前契邀,同時在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,解析守衛(wèi)就被調(diào)用
全局后置鉤子:
router.afterEach((to, from) => {})
路由獨享的守衛(wèi):
const router = new Router({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {}
}
]
})
組件內(nèi)的守衛(wèi):
export default {
name: 'Foo',
beforeRouteEnter(to, from, next) {
// 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
// 不失暴!能坯门!獲取組件實例 `this`
// 因為當(dāng)守衛(wèi)執(zhí)行前,組件實例還沒被創(chuàng)建
// 可以通過傳一個回調(diào)給 next來訪問組件實例逗扒。在導(dǎo)航被確認的時候執(zhí)行回調(diào)古戴,并且把組件實例作為回調(diào)方法的參數(shù)
next(vm => {
// 通過 `vm` 訪問組件實例
})
},
beforeRouteUpdate (to, from, next) {
// 在當(dāng)前路由改變,但是該組件被復(fù)用時調(diào)用
// 舉例來說矩肩,對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id现恼,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時候,
// 由于會渲染同樣的 Foo 組件黍檩,因此組件實例會被復(fù)用叉袍。而這個鉤子就會在這個情況下被調(diào)用。
// 可以訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導(dǎo)航離開該組件的對應(yīng)路由時調(diào)用
// 可以訪問組件實例 `this`
}
}
- 路由元信息
meta: { requiresAuth: true }
訪問元信息:
路由是可以嵌套的刽酱,因此一個路由匹配成功后喳逛,可能匹配多個路由記錄
$route.matched數(shù)組
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 確保一定要調(diào)用 next()
}
})
- 頁面滾動
const router = new Router({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滾動到哪個的位置
return { x: 0, y: 0 }
}
})
- 路由懶加載
const Home = () => import('@/pages/home/Home')
(resolve) => require(['pages/marketing-center/mission-medal/mission-rules/mission-rules'], resolve)
8. vuex
State、Getter棵里、Mutation润文、Action姐呐、Module
為什么要用vuex:
當(dāng)多個組件共享狀態(tài)時(多個視圖依賴同一狀態(tài),不同視圖的行為需要變更同一狀態(tài))
vuex和單純的全局對象有兩點不同:
1.vuex的存儲是響應(yīng)式的典蝌,當(dāng)vue組件從store中讀取狀態(tài)時曙砂,若store中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會得到高效更新骏掀。
2.不能直接改變store中的狀態(tài)麦轰。改變狀態(tài)的唯一途徑就是顯示提交mutation。
const store = new Vuex.Store({
state: {
count: 0
},
mutation: {
increment(state) {
state.count++
}
}
})
const app = new Vue({
el: '#app',
store
})
this.$store.state.count
this.$store.commit('increment')
- mapState輔助函數(shù)
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['count'])
}
}
- Getter
就像計算屬性一樣砖织,getter的返回值會根據(jù)它的依賴被緩存起來,且只有當(dāng)依賴值發(fā)生了改變才會被重新計算末荐。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
通過屬性訪問:
this.$store.getters.doneTodos
通過方法訪問:
定義時返回一個函數(shù):
getters: {
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
訪問時可以傳參數(shù)查詢:
this.$store.getters.getTodoById(2)
- Mutation
更改vuex的store中狀態(tài)的唯一方法是提交mutation
mutation必須是同步函數(shù)
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
state.count++
}
}
})
this.$store.commit('increment')
或者
methods: {
...mapMutations([
// 將 `this.increment()` 映射為 `this.$store.commit('increment')`
'increment'
])
}
- Action
Action類似于mutation侧纯,不同在于:
Action提交的是mutation,而不是直接變更狀態(tài)
Action可以包含任意異步操作
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
// 可以異步操作
setTimeout(() => {
context.commit('increment')
}, 1000)
}
}
})
分發(fā)Action:
this.$store.dispatch('increment')
或者
methods: {
...mapActions(['increment'])
}
- Module
由于使用單一狀態(tài)樹甲脏,當(dāng)應(yīng)用變得復(fù)雜時眶熬,store對象會非常臃腫。
因此块请,vuex允許我們將store分割成模塊(module)娜氏,每個模塊擁有自己的state、mutation墩新、action贸弥、getter、以及嵌套子模塊海渊。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
this.$store.state.a // -> moduleA 的狀態(tài)
this.$store.state.b // -> moduleB 的狀態(tài)
nodeJs
- ECMAScript(語言基礎(chǔ)绵疲,如:語法、數(shù)據(jù)類型結(jié)構(gòu)以及一些內(nèi)置對象)
- os(操作系統(tǒng))
- file(文件系統(tǒng))
var fs = require('fs')
fs.readFile('文件名', 'utf-8', function(err, data){})
fs.readFileSync('文件名', 'utf-8')
fs.writeFile('輸出文件名', data, function(err){})
fs.writeFile('輸出文件名', data)
fs.stat('文件名', function(err, stat){
if (err) {
} else {
// 是否是文件:
console.log('isFile: ' + stat.isFile());
// 是否是目錄:
console.log('isDirectory: ' + stat.isDirectory());
if (stat.isFile()) {
// 文件大小:
console.log('size: ' + stat.size);
// 創(chuàng)建時間, Date對象:
console.log('birth time: ' + stat.birthtime);
// 修改時間, Date對象:
console.log('modified time: ' + stat.mtime);
}
}
})
- stream
var fs = require('fs')
// 打開一個流
var rs = fs.createReadStream('文件名', 'uft-8')
rs.on('data', function(chunk){}) // data可能有多次臣疑,每次傳遞的chunk是流的一部分
rs.on('end', function(){})
rs.on('error', function(err){})
// 用流寫入文件
var ws = fs.createWriteStream('輸出文件名', 'utf-8')
ws.write('文本數(shù)據(jù)盔憨。。讯沈。')
ws.write(newBuffer('用流寫二進制數(shù)據(jù)', 'utf-8')
ws.end()
// 用流復(fù)制
var rs = fs.createReadStream('sample.txt');
var ws = fs.createWriteStream('copied.txt');
rs.pipe(ws);
- http(網(wǎng)絡(luò)系統(tǒng))
var http = require('http');
// 創(chuàng)建http server郁岩,并傳入回調(diào)函數(shù):
var server = http.createServer(function (request, response) {
// 回調(diào)函數(shù)接收request和response對象,
// 獲得HTTP請求的method和url:
console.log(request.method + ': ' + request.url);
// 將HTTP響應(yīng)200寫入response, 同時設(shè)置Content-Type: text/html:
response.writeHead(200, {'Content-Type': 'text/html'});
// 將HTTP響應(yīng)的HTML內(nèi)容寫入response:
response.end('<h1>Hello world!</h1>');
});
// 讓服務(wù)器監(jiān)聽8080端口:
server.listen(8080);
- web框架(koa2)
對http有封裝,使用Promise并配合async來實現(xiàn)異步缺狠。
// 導(dǎo)入koa问慎,和koa 1.x不同,在koa2中儒老,我們導(dǎo)入的是一個class蝴乔,因此用大寫的Koa表示:
const Koa = require('koa');
// 創(chuàng)建一個Koa對象表示web app本身:
const app = new Koa()
// 對于任何請求,app將調(diào)用該異步函數(shù)處理請求:
app.use(async (ctx, next) => {
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello, koa2!</h1>';
});
// 在端口3000監(jiān)聽:
app.listen(3000);
- 處理不同的URL(koa-router)
const Koa = require('koa');
// 注意require('koa-router')返回的是函數(shù):
const router = require('koa-router')();
const app = new Koa();
// log request URL:
app.use(async (ctx, next) => {
console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);
await next();
});
// add url-route:
router.get('/hello/:name', async (ctx, next) => {
var name = ctx.params.name;
ctx.response.body = `<h1>Hello, ${name}!</h1>`;
});
router.get('/', async (ctx, next) => {
ctx.response.body = '<h1>Index</h1>';
});
// add router middleware:
app.use(router.routes());
app.listen(3000);
console.log('app started at port 3000...');
- 處理post請求驮樊,獲取body內(nèi)容(koa-bodyparser)
const Koa = require('koa');
const app = new Koa();
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
- database(數(shù)據(jù)庫)
//引入數(shù)據(jù)庫
var mysql=require('mysql');
//實現(xiàn)本地鏈接
var connection = mysql.createConnection({
host: 'localhost',
user: 'user',
password: '123456',
database: 'test'
})
connection.query('SELECT * FROM users WHERE id = ?', ['123'], function(err, rows) {});
connection.query("INSERT INTO demo SET ?", post, function (error, results, fields) {})
...
- ORM框架(Sequelize)
const Sequelize = require('sequelize');
// 連接數(shù)據(jù)庫
let sequelize = new Sequelize(config.database, config.username, config.password, {
host: config.host,
dialect: config.dialect,
pool: config.pool
});
sequelize.define(tableName, attrs, {
tableName,
timestamps: false,
freezeTableName: true,
// 鉤子函數(shù)薇正,統(tǒng)一設(shè)置id片酝、createdAt等這些基礎(chǔ)字段的值
hooks: {
beforeValidate: function (obj) {
let now = Date.now();
if (obj.isNewRecord) {
if (!obj.id) {
obj.id = generateId();
}
obj.createdAt = now;
obj.updatedAt = now;
obj.version = 0;
obj.isDelete = false;
} else {
obj.updatedAt = Date.now();
obj.version++;
}
}
}
});