摘要:知識(shí)點(diǎn)目錄基于根據(jù)個(gè)人理解對(duì)每個(gè)知識(shí)點(diǎn)附上的答案,有錯(cuò)誤歡迎大家指出。結(jié)構(gòu)化也是為了增加代碼可讀性,提升網(wǎng)頁質(zhì)量,比如表示文檔頁眉頁腳,表示導(dǎo)航等。提供標(biāo)簽新增容器標(biāo)簽,結(jié)合繪制圖形路徑文本等。
知識(shí)點(diǎn)目錄基于 https://segmentfault.com/a/1190000018603454html
根據(jù)個(gè)人理解對(duì)每個(gè)知識(shí)點(diǎn)附上的答案,有錯(cuò)誤歡迎大家指出。
大部分情況,采用div+css就可以實(shí)現(xiàn)靜態(tài)頁面,但是這樣的布局會(huì)導(dǎo)致文檔結(jié)構(gòu)不夠清晰,而且不利于瀏覽器的讀取。而如果采用語義強(qiáng)的標(biāo)簽,比如用H系列標(biāo)簽表示標(biāo)題,strong表示強(qiáng)調(diào)等,這樣就能提升網(wǎng)站的可讀性,便與團(tuán)隊(duì)開發(fā)和維護(hù)。
結(jié)構(gòu)化也是為了增加代碼可讀性,提升網(wǎng)頁質(zhì)量,比如header、footer表示文檔頁眉頁腳,nav表示導(dǎo)航等。
標(biāo)題 內(nèi)容
h1標(biāo)簽頁面只能出現(xiàn)一次,權(quán)重最高
減少div標(biāo)簽的使用,盡量使用語義化強(qiáng)的標(biāo)簽
注重meta標(biāo)簽的使用,比如name屬性設(shè)置為description、keywords等,對(duì)搜索引擎的索引有幫助。
注重a標(biāo)簽和img標(biāo)簽的鏈接(title)和圖片說明(alt)
減少http請(qǐng)求次數(shù),合理設(shè)置http緩存(合并css、js、圖片等外部資源文件)
減少圖片數(shù)量,小圖標(biāo)可以用精靈圖的方式
啟用文件壓縮等
增加語義標(biāo)簽
header、footer、nav、section文檔中的一節(jié)、article頁面的獨(dú)立內(nèi)容區(qū)域、aside頁面?zhèn)冗厵趦?nèi)容、detailes文檔某個(gè)細(xì)節(jié)部分、summary包含details元素的標(biāo)題、dialog對(duì)話框
增強(qiáng)表單
提供input更多輸入類型,如color、date、email、number、range、tel、week、url、search等;新的表單元素datalist(其id屬性與input的list屬性綁定,實(shí)現(xiàn)選項(xiàng)列表輸入);新表單元素keygen、output等;新增placehoder、required、pattern、min、max、step、height、width、autofocus、multiple屬性。
提供audio、video標(biāo)簽
新增canvas容器標(biāo)簽,結(jié)合js繪制圖形、路徑、文本等。
還有moveTo(x,y)線條開始坐標(biāo)、lineTo(x,y)線條結(jié)束坐標(biāo); fillText(text,x,y)實(shí)心文本、strokeText(text,x,y)心文本; createLinearGradient(x,y,x1,y1) - 創(chuàng)建線條漸變 createRadialGradient(x,y,r,x1,y1,r1) - 創(chuàng)建一個(gè)徑向/圓漸變 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存儲(chǔ): sessionStorage(生命周期為關(guān)閉瀏覽器) 5M localStorage(永久生效,除非手動(dòng)刪除) 20M 全屏: 允許用戶自定義網(wǎng)上任一元素全屏顯示: requestFullScreen() 開啟全屏 cancelFullScreen() 關(guān)閉全屏 文件讀取: FileList對(duì)象,input上傳文件后返回該對(duì)象 FileReader對(duì)象: 讀取:readAsDataURL(file.files[0]) 監(jiān)聽: onload 拖拽: 給元素設(shè)置draggable="true",其中img和a標(biāo)簽?zāi)J(rèn)可拖拽 事件監(jiān)聽: 拖拽元素: drag: 拖拽過程中一直調(diào)用 dragstart: 拖拽開始調(diào)用 dragleave: 鼠標(biāo)離開拖拽元素調(diào)用 dragend: 拖拽結(jié)束調(diào)用 目標(biāo)元素: dragenter:拖拽元素進(jìn)入時(shí)調(diào)用 dragover:停留在目標(biāo)元素上時(shí)調(diào)用,注意阻止瀏覽器默認(rèn)行為(event.preventDefault()) drop:當(dāng)在目標(biāo)元素上松開鼠標(biāo)時(shí)調(diào)用 dragleave:當(dāng)鼠標(biāo)離開目標(biāo)元素時(shí)調(diào)用 可以通過dataTransfer拿到當(dāng)前的拖拽進(jìn)來的文件列表 多媒體: load()、play()、pause()css
標(biāo)簽~
類~
id~
并集~(逗號(hào))
交集~(標(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
繼承性(父元素設(shè)置屬性,子元素默認(rèn)也生效。color-|font-|text-|line-開頭的可以繼承)
層疊性(多個(gè)選擇器選中同一元素,修改同一屬性時(shí)。覺得如何生效需要根據(jù)優(yōu)先級(jí)判斷)
優(yōu)先級(jí)
BFC(Block Formatting Context)概念
格式化上下文,指一個(gè)獨(dú)立的渲染區(qū)域或者說是一個(gè)隔離的獨(dú)立容器
形成BFC的條件
浮動(dòng)元素,float除none以外的值
定位元素,position(absolute、fixed)
display(inline-block、table-cell、table-caption)
overflow(除visible以外的值)hidden、auto、scroll
body根元素
BFC的特性
是個(gè)獨(dú)立容器,內(nèi)部元素不會(huì)影響外面元素
不被浮動(dòng)元素覆蓋
父元素是BFC時(shí),不會(huì)被子元素的margin擠下來
BFC容器的高度,內(nèi)部浮動(dòng)元素也參與計(jì)算(比如overflow:hidden清除浮動(dòng),可以讓內(nèi)部浮動(dòng)元素也能撐開父元素高度)
將元素類比為一個(gè)盒子,有外邊距、邊框、內(nèi)邊距、寬度、高度五個(gè)元素決定齊所占的元素空間大小
常見問題:
padding內(nèi)邊距會(huì)導(dǎo)致元素的寬度和高度變化
可通過box-sizing:border-box鎖定元素寬高;
content-box 元素的寬高 = 邊框 + 內(nèi)邊距 + 內(nèi)容寬高 border-box 元素的寬高 = width/height的寬高
margin合并現(xiàn)象(默認(rèn)垂直方向的外邊距不會(huì)疊加,會(huì)出現(xiàn)合并,誰的邊距大就按照誰的來);
將其中一個(gè)元素放入一個(gè)BFC模式的元素內(nèi)(不推薦,會(huì)改變文檔結(jié)構(gòu));一般會(huì)給其中一個(gè)元素設(shè)置margin-bottom直接給夠距離
margin塌陷現(xiàn)象,內(nèi)部盒子的外邊距會(huì)將父盒子頂下來
利用BFC機(jī)制,比如父盒子設(shè)置overflow:hidden;
寬度高度問題
內(nèi)容寬高 = width/height 元素寬高 = 邊框+內(nèi)邊距+width/height;設(shè)置box-sizing:border-box后值為:width/height 元素空間的寬高:外邊距+邊框+內(nèi)邊距+width/height
css預(yù)處理器方便開發(fā),無需考慮瀏覽器兼容問題,代碼模塊化、清晰簡潔scss 是 sass3 引入新的語法,其語法完全兼容 css3,并且繼承了 sass 的強(qiáng)大功能。sass 和 scss 其實(shí)是同一種東西,我們平時(shí)都稱之為 sass,兩者之間不同之處有以下兩點(diǎn):1.文件擴(kuò)展名不同(.sass/.scss);2.語法書寫方式不同,sass 是以嚴(yán)格的縮進(jìn)式語法規(guī)則來書寫,不帶大括號(hào)({})和分號(hào)(;),而 scss 的語法書寫和我們的 css 語法書寫方式非常類似。
允許網(wǎng)頁寬度自動(dòng)調(diào)整
寬度百分比
相對(duì)字體rem/em
流動(dòng)布局,利用float或者display:fixed等
使用css media模塊
@media screen and (min-width: 768px) and (max-width: 1024px) ...
圖片自適應(yīng),max-width/min-width等
標(biāo)準(zhǔn)文檔流(padding+margin)+浮動(dòng)+定位
百分比布局
flex彈性布局
grid柵格布局(display:grid),使用框架中的類名來替代,本質(zhì)上還是百分比布局
JavaScript基本: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(),可以解決判斷所有類型
算術(shù)運(yùn)算符(+、-、*、/、%、++、--)
賦值運(yùn)算符(=、+=、-=、*=、/=、%=)
條件運(yùn)算符(三元表達(dá)式)
邏輯運(yùn)算符(!、&&(短路,第一個(gè)值為false,第二個(gè)值不用檢測了)、||(短路,第一個(gè)值為true,第二個(gè)值不用檢測了))
比較運(yùn)算符(雙等于、===、!=、>、<、>=、<=)
位運(yùn)算符(非~、按位與&、按位或|、異或^、左移<<、有符號(hào)右移>>、無符號(hào)右移>>>)
顯示類型轉(zhuǎn)換(Boolean()、Number()、String()、Object()等)
隱示類型轉(zhuǎn)換
+運(yùn)算符的一個(gè)值如果是字符串,它會(huì)把另一個(gè)值轉(zhuǎn)為字符串拼接 一元+,會(huì)將值試圖轉(zhuǎn)為數(shù)字,如 +"5" 一元!,會(huì)將值試圖轉(zhuǎn)為boolean,再取反 在做比較運(yùn)算時(shí),也會(huì)發(fā)生很多隱示轉(zhuǎn)換: 對(duì)象轉(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等)
函數(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)用,比如某個(gè)對(duì)象中的行為 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都是為了改變某個(gè)函數(shù)運(yùn)行時(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是為了動(dòng)態(tài)改變this而出現(xiàn)的,當(dāng)一個(gè)object沒有某個(gè)方法(本例子中banana沒有say方法), 但是其他的有(本例子中apple有say方法),我們可以借助call或apply用其它對(duì)象的方法來操作。 二者區(qū)別: func.call(this, arg1, arg2); 若干個(gè)參數(shù) func.apply(this, [arg1, arg2]); 數(shù)組參數(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 使用其方法。 驗(yàn)證是否是數(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 是返回對(duì)應(yīng)函數(shù),便于稍后調(diào)用;apply 、call 則是立即調(diào)用
實(shí)參形參傳值問題
基本類型,按值傳遞(函數(shù)內(nèi)部修改形參值,不會(huì)影響外部實(shí)參值) 引用類型,按對(duì)象共享傳遞 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ù)接受對(duì)象實(shí)參引用的副本(既不是按值傳遞的對(duì)象副本,也不是按引用傳遞的隱式引用)。 它和按引用傳遞的不同在于:在共享傳遞中對(duì)函數(shù)形參的賦值,不會(huì)影響實(shí)參的值。如下面例子中,不可以通過修改形參o的值,來修改obj的值。 也就是說不可以改變引用類型的指針,只可以改變這個(gè)對(duì)象的屬性
數(shù)組方法
concat()拼接數(shù)組,參數(shù)是任意個(gè)值或者數(shù)組,返回新數(shù)組,不影響原數(shù)組 join()將數(shù)組的值用指定分隔符轉(zhuǎn)成字符串,不傳參默認(rèn)為逗號(hào),返回新值,不影響原值 pop()刪除并返回?cái)?shù)組最后一個(gè)元素 push()向數(shù)組末尾添加一個(gè)或多個(gè)元素,返回?cái)?shù)組新長度 shift()刪除并返回?cái)?shù)組第一個(gè)元素 unshift()想數(shù)組開頭添加一個(gè)或多個(gè)元素,返回?cái)?shù)組新長度 slice(start,end)包含頭不包含尾,返回新值對(duì)原值沒有影響 splice(index,howmany,item1...,itemX) 可用于替換,刪除,添加; howmany表示要?jiǎng)h除的個(gè)數(shù),返回被刪除的值組成的數(shù)組,原數(shù)組被修改 sort()對(duì)數(shù)組元素排序,修改原值 reverse()點(diǎn)到數(shù)組中元素的順序,修改原值 every()是對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果每一項(xiàng)都返回true,則返回true some()是對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果對(duì)任一項(xiàng)返回true,則返回true filter()是對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回該函數(shù)返回true的項(xiàng)組成數(shù)組 map()是對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成數(shù)組 reduce()從數(shù)組元素中計(jì)算出一個(gè)值 arr.indexOf("")查找數(shù)組,判斷數(shù)組中是否含有某一項(xiàng)
字符串
三個(gè)字符方法: charAt()返回給定位置的字符 charCodeAt()返回給定位置的字符編碼 str[index]直接用方括號(hào)加索引也能返回指定位置的字符,IE7及更早版本不支持 操作字符串方法: concat()用于拼接字符串,可傳任意個(gè)參數(shù) slice(start,end)包含頭不包含尾,返回新值對(duì)原值沒有影響 substring(start,end)包含頭不包含尾,返回新值對(duì)原值沒有影響 substr(start,num)第二個(gè)參數(shù)為個(gè)數(shù),返回新值對(duì)原值沒有影響 字符串位置方法: indexOf()從前往后找、lastIndexOf()從后往前找 大小寫: toLowerCase()、toLocaleLowerCase()、toUpperCase()、toLocaleUpperCase() 都是返回新值對(duì)原值沒有影響 字符串的模式匹配方法: match()參數(shù)為正則表達(dá)式或者RegExp對(duì)象,返回匹配的數(shù)組 search()返回字符串中第一個(gè)匹配項(xiàng)的索引,如果沒找到就返回-1 replace(egexp/substr, replacement/function),返回新值對(duì)原值沒有影響 split()基于分隔符分割字符串,返回新數(shù)組對(duì)原值沒有影響 trim()刪除字符串前后所有空格,返回新值對(duì)原值沒有影響
格式:/正則表達(dá)式主體/修飾符(可選) d: 0-9任意一個(gè)數(shù)字 w: 數(shù)字、字母、下劃線 0-9 a-z A-Z _ s: 空格或者空白 (): 分組 [a-z]: 區(qū)間內(nèi)任意一個(gè) *: 0到多個(gè) +: 1到多個(gè) {n}: 正好n次 {n,m}: n-m次 比如手機(jī):/1[34578]d{9}/
作用域
全局作用域、函數(shù)作用域 ES6引入let和const關(guān)鍵字,隨即帶來塊級(jí)作用域的概念
作用域鏈
對(duì)象有一個(gè)內(nèi)部屬性[[Scope]],該屬性包含了函數(shù)被創(chuàng)建的作用域中對(duì)象的集合,這個(gè)集合被稱為函數(shù)的作用域鏈。 js解析某個(gè)變量時(shí),會(huì)從代碼嵌套的最內(nèi)層開始,如果沒找到,會(huì)順著作用域鏈向上查找。
閉包
函數(shù)內(nèi)部返回一個(gè)函數(shù) 對(duì)外部暴露指定行為,但還是能用到自己作用域內(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(); } } })()
構(gòu)造函數(shù)、原型和實(shí)例之間的關(guān)系
構(gòu)造函數(shù)的prototype指向一個(gè)原型對(duì)象, 原型對(duì)象的constructor指回構(gòu)造函數(shù), 實(shí)例的內(nèi)部指針__proto__指向原型對(duì)象。 通過調(diào)用構(gòu)造函數(shù)產(chǎn)生的實(shí)例,都有一個(gè)內(nèi)部屬性,指向了原型對(duì)象。所以實(shí)例能夠訪問原型對(duì)象上的所有屬性和方法 例子: 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[實(shí)例] --> B A[構(gòu)造函數(shù)Dog] --> B[Dog的原型對(duì)象] B --> A
原型鏈、繼承
//定義一個(gè) 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指針,指向一個(gè) Animal 實(shí)例 Dog.prototype = new Animal(); Dog.prototype.speak = function () { alert(this.type); } var doggie = new Dog("jiwawa"); doggie.superSpeak(); //Animal 如果將Dog的prototype指針指向另一個(gè)Animal的實(shí)例,那么Dog的實(shí)例就能調(diào)用Animal的屬性和方法。
規(guī)律一:函數(shù)名加圓括號(hào)直接調(diào)用,函數(shù)上下文是 window 對(duì)象。 規(guī)律二:函數(shù)如果作為一個(gè)對(duì)象的方法,對(duì)象使用點(diǎn)方法進(jìn)行調(diào)用,那么函數(shù)的上下文就是這個(gè)對(duì)象。 規(guī)律三:函數(shù)是事件處理函數(shù),那么函數(shù)的上下文就是觸發(fā)這個(gè)事件的對(duì)象。 規(guī)律四:函數(shù)被定時(shí)器調(diào)用時(shí),上下文是 window 對(duì)象。 規(guī)律五:數(shù)組中存放的函數(shù),被數(shù)組索引調(diào)用,函數(shù)上下文就是這個(gè)數(shù)組。
JS單線程(主線程) ↓ 單線程導(dǎo)致任務(wù)需要排隊(duì),如果前一個(gè)任務(wù)耗時(shí)很長,后面的就一直等著。 如果排隊(duì)是因?yàn)橛?jì)算了大,CPU忙不過來,倒也算了。 很多時(shí)候沒事因?yàn)镮O設(shè)備慢(比如Ajax操作從網(wǎng)絡(luò)讀取數(shù)據(jù)) ↓ 同步任務(wù)和異步任務(wù) 同步:在主線程上排隊(duì)執(zhí)行的任務(wù),前一個(gè)完成,才執(zhí)行后一個(gè)。 異步:不進(jìn)入主線程,而進(jìn)入“任務(wù)隊(duì)列”,只有“任務(wù)隊(duì)列”通知主線程,某個(gè)異步任務(wù)可以執(zhí)行了,該任務(wù)才會(huì)進(jìn)入主線程執(zhí)行。 只要主線程空了,就會(huì)去讀取"任務(wù)隊(duì)列",這就是JavaScript的運(yùn)行機(jī)制。這個(gè)過程會(huì)不斷重復(fù) ↓ "任務(wù)隊(duì)列"是一個(gè)事件(消息)的隊(duì)列,IO設(shè)備完成一項(xiàng)任務(wù),就在"任務(wù)隊(duì)列"中添加一個(gè)事件,表示相關(guān)的異步任務(wù)可以進(jìn)入"執(zhí)行棧"了。主線程讀取"任務(wù)隊(duì)列",就是讀取里面有哪些事件。 "任務(wù)隊(duì)列"中的事件,除了IO設(shè)備的事件以外,還包括一些用戶產(chǎn)生的事件(比如鼠標(biāo)點(diǎn)擊、頁面滾動(dòng)等等)。只要指定過回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入"任務(wù)隊(duì)列",等待主線程讀取。 所謂"回調(diào)函數(shù)"(callback),就是那些會(huì)被主線程掛起來的代碼。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開始執(zhí)行異步任務(wù),就是執(zhí)行對(duì)應(yīng)的回調(diào)函數(shù)。 主線程的讀取過程基本上是自動(dòng)的,只要執(zhí)行棧一清空,"任務(wù)隊(duì)列"上第一位的事件就自動(dòng)進(jìn)入主線程。但是,由于"定時(shí)器"功能,主線程首先要檢查一下執(zhí)行時(shí)間,某些事件只有到了規(guī)定的時(shí)間,才能返回主線程。 ↓ 主線程從"任務(wù)隊(duì)列"中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為Event Loop(事件循環(huán))。 執(zhí)行棧中的代碼(同步任務(wù)),總是在讀取"任務(wù)隊(duì)列"(異步任務(wù))之前執(zhí)行。
Ajax 是一種在無需重新加載整個(gè)網(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è)置請(qǐng)求頭 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)知識(shí)點(diǎn): GET 更簡單更快,無法發(fā)送大數(shù)據(jù),無法緩存 POST 更大更穩(wěn)定,可發(fā)大數(shù)據(jù),可緩存 readyState(0: 請(qǐng)求未初始化 1: 服務(wù)器連接已建立 2: 請(qǐng)求已接收 3: 請(qǐng)求處理中 4: 請(qǐng)求已完成,且響應(yīng)已就緒) status(1字頭:消息,代表請(qǐng)求已被接受,需要繼續(xù)處理; 2字頭:成功; 3字頭:重定向; 4字頭:請(qǐng)求錯(cuò)誤; 5、6字頭:服務(wù)器錯(cuò)誤) 常見:200成功、304緩存、404未找到頁面、500服務(wù)器錯(cuò)誤
普通使用: import axios from "axios" axios.get/post(url, params).then(function(){}).catch(function(){}) 自定義axios常見使用方式: let myAxios = axios.create({ baseURL: "", timeout: 30000, headers: {}, ... }) // 請(qǐng)求攔截器 myAxios.interceptors.request.use( function (config) { // 發(fā)送請(qǐng)求之前做些什么,比如token if (store.state.Token) { config.headers.Authorization = "前綴" + store.state.Token } reutrn config }, function (error) { // 對(duì)請(qǐng)求錯(cuò)誤,做些什么 return Promise.reject(error) } ) // 響應(yīng)攔截器 myAxios.interceptors.response.use( function (response) { // 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么 return response.data }, function (error) { // 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么, 比如后臺(tái)返回token失效的狀態(tài)碼,就需要跳轉(zhuǎn)login if (error && error.response) { switch (error.response.status) { case 400: error.message = "請(qǐng)求出錯(cuò)" 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) } )
回調(diào)函數(shù)
事件監(jiān)聽
ES6/Promise對(duì)象(避免層層嵌套的異步回調(diào),代碼更清晰)
ES6/Generator函數(shù)
ES7/async和await
瀏覽器Trident(IE)、Gecko9(火狐)、Blink(Chrome、Opera)、Webkit(Safari)
HTML解釋器 CSS解釋器 圖層布局計(jì)算模塊:布局計(jì)算每個(gè)對(duì)象的精確位置和大小 視圖繪制模塊:進(jìn)行具體節(jié)點(diǎn)的圖像繪制,將像素渲染到屏幕上 JavaScript引擎:編譯執(zhí)行JS代碼
運(yùn)行機(jī)制: 瀏覽器使用http/https向服務(wù)的請(qǐng)求頁面 ↓ 解析HTML,構(gòu)建DOM樹 ↓ 計(jì)算DOM樹上的CSS ↓ (排版)根據(jù)CSS屬性渲染元素,得到內(nèi)存中的位圖 ↓ (可選步驟)對(duì)位圖進(jìn)行合成,提升后續(xù)繪制速度 ↓ 繪制到界面上
解析HTML,生成DOM樹(DOM) 解析CSS,生成CSSOM樹(CSSOM) 將DOM和CSSOM合并,生成渲染樹(Render-Tree) 計(jì)算渲染樹的布局(Layout) 將布局渲染到屏幕上(Paint)
JavaScript分三個(gè)部分: ECMAScript標(biāo)準(zhǔn) --- 基本語法 DOM --- 文檔對(duì)象模型,操作頁面元素的 BOM --- 瀏覽器對(duì)象模型,操作瀏覽器的 瀏覽器頂級(jí)對(duì)象: window 頁面頂級(jí)對(duì)象: document 頁面中所有內(nèi)容都屬于瀏覽器
BOM(Browser Object Model)瀏覽器對(duì)象模型
BOM是獨(dú)立于內(nèi)容的、可以與瀏覽器窗口進(jìn)行互動(dòng)的對(duì)象結(jié)構(gòu),其由多個(gè)對(duì)象組成,其中代表瀏覽器窗口的Window對(duì)象是其頂層對(duì)象。 可刷新瀏覽器、后退、前進(jìn)、在瀏覽器中輸入U(xiǎn)RL等。 alert()、prompt()、confirm() onload()、onunload() setTimeout()、clearTimeout()、setInterval()、clearInterval() loaction、history、navigator
DOM(Document Object Model)文檔對(duì)象模型
document. getElementById() getElementsByTagName() getElementsByName() getElementsByClassName() querySelector() createElement() appendChild()
監(jiān)聽事件
addEventListener("事件名","事件處理函數(shù)","布爾值false冒泡,true捕獲") removeEventListener("事件名","事件處理函數(shù)","布爾值") preventDefault()阻止默認(rèn)事件 stopPropagation()阻止事件冒泡 其他常用事件: onclick、ondbclick、 onmousedown、onmouseup、onmouseout、onmousemove、onmouseover
事件代理(事件委托)
原理:利用事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類型的所有事件 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); } } }
強(qiáng)緩存:用戶發(fā)送的請(qǐng)求,直接從客戶端緩存中獲取,不發(fā)送請(qǐng)求到服務(wù)器,不與服務(wù)器發(fā)生交互行為。 協(xié)商緩存:用戶發(fā)送的請(qǐng)求,發(fā)送到服務(wù)器后,由服務(wù)器判定是否從緩存中獲取資源。 兩者共同點(diǎn):客戶端獲得的數(shù)據(jù)最后都是從客戶端緩存中獲得。 兩者的區(qū)別:從名字就可以看出,強(qiáng)緩存不與服務(wù)器交互,而協(xié)商緩存則需要與服務(wù)器交互。
為什么會(huì)跨域:瀏覽器的同源策略(阻止不同協(xié)議或者域名或者端口的請(qǐng)求) 解決方法: JSONP(只能發(fā)GET請(qǐng)求) 空iframe加form CORS(跨域資源共享):響應(yīng)頭設(shè)置Access-Control-Allow-Origin等... 代理 ...關(guān)于網(wǎng)絡(luò)協(xié)議
HTTP(Hyper Text Transfer Protocol)超文本傳輸協(xié)議: 基于TCP/IP通信協(xié)議傳遞數(shù)據(jù),用于從萬維網(wǎng)服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議 主要特點(diǎn): 簡單快速、靈活、無連接(完成請(qǐng)求就斷開鏈接)、無狀態(tài)、支持B/S C/S
URL
HTTP使用統(tǒng)一資源標(biāo)識(shí)符URI來傳輸數(shù)據(jù)和建立連接,統(tǒng)一資源定位符URL是URI的一種特殊類型 URL:協(xié)議+域名+端口+虛擬目錄+文件名+錨(#)+參數(shù)(?)
Request
請(qǐng)求行(請(qǐng)求方法 URL 協(xié)議版本) 請(qǐng)求頭(頭部字段名 值...) 空行(一定有一個(gè)空行)請(qǐng)求數(shù)據(jù) 請(qǐng)求數(shù)據(jù)
Response
狀態(tài)行(協(xié)議版本 狀態(tài)碼 狀態(tài)消息) 消息報(bào)頭 空行 響應(yīng)正文(服務(wù)器返回給客戶端的文本信息)
狀態(tài)碼
1xx:指示信息--表示請(qǐng)求已接收,繼續(xù)處理 2xx:成功--表示請(qǐng)求已被成功接收、理解、接受 3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作 4xx:客戶端錯(cuò)誤--請(qǐng)求有語法錯(cuò)誤或請(qǐng)求無法實(shí)現(xiàn) 5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求 常見: 200 OK:客戶端請(qǐng)求成功 400 Bad Request:客戶端請(qǐng)求有語法錯(cuò)誤,不能被服務(wù)器所理解 401 Unauthorized:請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用 403 Forbidden:服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù) 404 Not Found:請(qǐng)求資源不存在,eg:輸入了錯(cuò)誤的URL 500 Internal Server Error:服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤 503 Server Unavailable:服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常
請(qǐng)求方法
GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE
HTTP工作原理
建立TCP連接(三次握手),客戶端連接服務(wù)器 ↓ 發(fā)送HTTP請(qǐng)求 ↓ 服務(wù)器接受請(qǐng)求,返回HTTP響應(yīng) ↓ 釋放TCP連接 ↓ 瀏覽器解析HTML內(nèi)容
GET和POST區(qū)別
GET: 請(qǐng)求數(shù)據(jù)附在URL后,地址欄可見 POST: 請(qǐng)求數(shù)據(jù)包在請(qǐng)求體中 GET: 長度有限(2083字節(jié)) POST: 理論上不限制大小,服務(wù)器常會(huì)對(duì)POST數(shù)據(jù)大小進(jìn)行限制 GET: 數(shù)據(jù)明文,不安全 POST: 安全
Cookie
客戶端緩存技術(shù) 瀏覽器的一種數(shù)據(jù)存儲(chǔ)功能,由服務(wù)器生成,發(fā)送給瀏覽器,以鍵值方式存儲(chǔ),下次請(qǐng)求,會(huì)把cookie發(fā)送給服務(wù)器,過期時(shí)長由expire決定
Session
會(huì)話緩存技術(shù) 類似客戶端的身份標(biāo)識(shí),由服務(wù)器生成,保存在服務(wù)器端,以鍵值方式存儲(chǔ),默認(rèn)30分鐘過期 客戶端每次像服務(wù)器發(fā)送請(qǐng)求,都帶上身份標(biāo)識(shí),服務(wù)器就知道請(qǐng)求來自誰??蛻舳顺S胏ookie方式保存標(biāo)識(shí)
Token
用戶登錄成功,服務(wù)器生成Token返回給客戶端 客戶端保存Token 客戶端每次請(qǐng)求攜帶Token 服務(wù)器校驗(yàn)Token
localStorage
生命周期永久,除非手動(dòng)清楚,存放大小一般5MB,存在客戶端
sessionStorage
當(dāng)前會(huì)話有效,關(guān)閉瀏覽器清楚,存放大小5MBD,存在客戶端關(guān)于ES6語法
變量聲明 let/const
變量名不自動(dòng)提示,提供塊級(jí)作用域
箭頭函數(shù)
() => {} 箭頭函數(shù)中沒有this,如果在箭頭函數(shù)內(nèi)使用this,該this是外層的this
模板字符串
使用``將字符串包裹,在其中可以使用${}來包裹一個(gè)變量或表達(dá)式
解析結(jié)構(gòu)
數(shù)組以序列號(hào)對(duì)應(yīng),對(duì)象根據(jù)屬性名對(duì)應(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ù)默認(rèn)參數(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());
展開運(yùn)算符
使用...可以將數(shù)組或者對(duì)象進(jìn)行展開 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})
對(duì)象字面量與class
當(dāng)屬性與值同名時(shí),可簡寫 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方法返回一個(gè)新的Promise實(shí)例,因此支持鏈?zhǔn)綄懛?,后面的then會(huì)等待前面then返回的Promise對(duì)象狀態(tài)發(fā)生變化,然后決定調(diào)用resolve還是reject。 .catch() .finally() ES2018引入, 不管promise最后狀態(tài),都會(huì)執(zhí)行 .all()將多個(gè)Promise實(shí)例包裝成一個(gè)新的Promise實(shí)例,只有子實(shí)例狀態(tài)都變?yōu)閒ulfilled,包裝實(shí)例才變?yōu)閒ulfilled,如果其中一個(gè)是rejected,那么包裝也是rejected。 .race()同all()方法,相當(dāng)于或操作,只要有一個(gè)實(shí)例狀態(tài)改變,包裝實(shí)例就會(huì)跟著改變 .resolve()將現(xiàn)有對(duì)象轉(zhuǎn)為Promise對(duì)象 .reject()返回一個(gè)狀態(tài)為rejected的Promise實(shí)例
Modules
Symbol(表示獨(dú)一無二的值)
Set和Map
Set類似于數(shù)組,但其成員的值都是唯一的,沒有重復(fù)的值 const s = new Set() const s1 = new Set([1,2,3,2,3]) [...s] add(value):添加某個(gè)值,返回 Set 結(jié)構(gòu)本身。 delete(value):刪除某個(gè)值,返回一個(gè)布爾值,表示刪除是否成功。 has(value):返回一個(gè)布爾值,表示該值是否為Set的成員。 clear():清除所有成員,沒有返回值。
類似于對(duì)象,也是鍵值對(duì)的集合,但是鍵不限于字符串,各種類型都可以當(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)沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個(gè)值),所以keys方法和values方法的行為完全一致
Proxy
在目標(biāo)對(duì)象之前架設(shè)一層“攔截”,外界訪問該對(duì)象,都必須先通過這層攔截 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): 攔截對(duì)象屬性的讀取,比如proxy.foo和proxy["foo"]。 set(target, propKey, value, receiver): 攔截對(duì)象屬性的設(shè)置,比如proxy.foo =v或proxy["foo"]=v,返回一個(gè)布爾值。 has(target, propKey): 攔截propKey in proxy的操作,返回一個(gè)布爾值 ...
Iterator和for...of循環(huán)
Iterator作用: 1. 為各種數(shù)據(jù)結(jié)構(gòu),提供一個(gè)統(tǒng)一的訪問接口 2. 使數(shù)據(jù)結(jié)構(gòu)的成員能夠按某種次序排列 3. 創(chuàng)造了一種新的遍歷命令for...of 遍歷器原理:創(chuàng)建一個(gè)指針指向數(shù)據(jù)結(jié)構(gòu)(Array/Set/Map/String/TypedArry/arguments/NodeList)的初始位置, 第一次調(diào)用指針對(duì)象的next方法,將指針指向第一個(gè)成員,第二次next指向第二個(gè),以此類推,直到結(jié)束位置。 for(let val of 數(shù)據(jù)結(jié)構(gòu)){}
export 和 export default
export與export default均可用于導(dǎo)出常量、函數(shù)、文件、模塊等 在一個(gè)文件或模塊中,export、import可以有多個(gè),export default僅有一個(gè) 通過export方式導(dǎo)出,在導(dǎo)入時(shí)要加{ },export default則不需要 export能直接導(dǎo)出變量表達(dá)式,export default不行Vue
v-text:綁定元素的文本內(nèi)容
v-html:綁定元素的innerHTML
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 - 添加事件偵聽器時(shí)使用 capture 模式。
.self - 只當(dāng)事件是從偵聽器綁定的元素本身觸發(fā)時(shí)才觸發(fā)回調(diào)。
.{keyCode | keyAlias} - 只當(dāng)事件是從特定鍵觸發(fā)時(shí)才觸發(fā)回調(diào)。比如 @click.enter="handleEnter"
.native - 監(jiān)聽組件根元素的原生事件。
.once - 只觸發(fā)一次回調(diào)。
.left - (2.2.0) 只當(dāng)點(diǎn)擊鼠標(biāo)左鍵時(shí)觸發(fā)。
.right - (2.2.0) 只當(dāng)點(diǎn)擊鼠標(biāo)右鍵時(shí)觸發(fā)。
.middle - (2.2.0) 只當(dāng)點(diǎn)擊鼠標(biāo)中鍵時(shí)觸發(fā)。
.passive - (2.3.0) 以 { passive: true } 模式添加偵聽器
v-bind:動(dòng)態(tài)綁定一個(gè)或多個(gè)特性或組件prop到表達(dá)式,縮寫":"; 比如 :class="{}"
修飾符:
.prop - 被用于綁定 DOM 屬性 (property)。(差別在哪里?)
.camel - (2.1.0+) 將 kebab-case 特性名轉(zhuǎn)換為 camelCase. (從 2.1.0 開始支持)
.sync (2.3.0+) 語法糖,會(huì)擴(kuò)展成一個(gè)更新父組件綁定值的 v-on 偵聽器。
v-model:數(shù)據(jù)雙向綁定
修飾符:
.lazy - 取代 input 監(jiān)聽 change 事件
.number - 輸入字符串轉(zhuǎn)為有效的數(shù)字
.trim - 輸入首尾空格過濾
v-slot:用于,縮寫#
v-pre:跳過這個(gè)元素和其子元素的編譯過程
v-cloak:與CSS規(guī)則[v-cloak]{display:none}一起使用
v-once:只渲染元素和組件一次。This will never change: {{msg}}
屬性
常用: vm.$refs:返回Object,獲取注冊過ref特性的所有DOM元素和組件實(shí)例 其他: vm.$data:Object,訪問Vue實(shí)例的data屬性 vm.$props:Object,訪問Vue實(shí)例的props屬性 vm.$el:Element,當(dāng)前組件的根DOM元素 vm.$options:Object,訪問Vue的初始化選項(xiàng) vm.$parent:獲取父實(shí)例 vm.$root:當(dāng)前組件樹的根實(shí)例 vm.$children vm.$slots:訪問具名插槽的內(nèi)容 vm.$scopedSlots:訪問作用域插槽的內(nèi)容 vm.$isServer vm.$attrs vm.$listeners
方法
常用: vm.$emit(eventName,[...args]):觸發(fā)當(dāng)前實(shí)例上的事件,常用于父子組件通信 vm.$watch:觀察 Vue 實(shí)例變化的一個(gè)表達(dá)式或計(jì)算屬性函數(shù) vm.$watch("a.b.c", function (newVal, oldVal) { // 做點(diǎn)什么 }) vm.$set(target,key,value) 其他: vm.$delete(target,key) vm.$on(event,callback):監(jiān)聽當(dāng)前實(shí)例上的自定義事件 vm.$once(event,callback):監(jiān)聽自定義事件,只觸發(fā)一次,觸發(fā)后自動(dòng)移除監(jiān)聽器 vm.$off([event,callback]):移除自定義事件 vm.$mount([elementOrSelector]):可用于給vue實(shí)例手動(dòng)掛載dom元素 vm.$forceUpdate():迫使vue實(shí)例重新渲染 vm.$nextTick([callback]):將回調(diào)延遲到下次DOM更新循環(huán)之后執(zhí)行。在修改數(shù)據(jù)之后立即使用它,然后等待 DOM 更新 vm.$destory():完全銷毀一個(gè)實(shí)例。清理它與其它實(shí)例的連接,解綁它的全部指令及事件監(jiān)聽器
beforeCreate 實(shí)例初始化之后調(diào)用 created 實(shí)例創(chuàng)建完成后被立即調(diào)用 beforeMount 掛載開始之前被調(diào)用 mounted 掛載到實(shí)例上去之后調(diào)用該鉤子 beforeUpdate 數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬 DOM 打補(bǔ)丁之前 updated 由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補(bǔ)丁,在這之后會(huì)調(diào)用該鉤子 activated keep-alive組件激活時(shí)調(diào)用 deactivated keep-alive組件停用時(shí)調(diào)用 beforeDestory 實(shí)例銷毀之前調(diào)用 destoryed 實(shí)例銷毀后調(diào)用 errorCaptured 當(dāng)捕獲一個(gè)來自子孫組件的錯(cuò)誤時(shí)被調(diào)用
組件注冊
全局注冊: Vue.component("name", { data () { return { ... } }, template: `` ... }) 局部注冊: var componentA = {} var componentB = {} var componentC = {} new Vue({ el: "#app", components: { componentA, componentB } })
父子
父給子傳值: 直接以屬性的方式,如果是動(dòng)態(tài)值可以用v-bind,子組件通過props接受值 子給父傳值: 通過自定義事件。 子組件通過$emit("faterEvent", ...params)觸發(fā)父組件的自定義事件,父組件自定義事件觸發(fā)一個(gè)自定義方法,其參數(shù)就是子組件傳過來的值。
兄弟
可借助同一個(gè)父組件通信
跨級(jí)
vuex
具名插槽
定義:調(diào)用: Here might be a page title
作用域插槽
讓插槽內(nèi)容能夠訪問子組件中才有的數(shù)據(jù) 定義:{{ user.lastName }} 調(diào)用:{{ slotProps.user.firstName }}
HTML: 入口(聲明式):出口: JavaScript: import Vue from "vue" import Router from "vue-router" Vue.use(Router) // 定義路由 const routes=[ {path: "/index", component: ()=>require("../index")} ] // 創(chuàng)建router實(shí)例并配置路由 const router = new Router({ routes }) // 根實(shí)例配置router const app = new Vue({ router })
可以在任何組件內(nèi)通過this.$router訪問路由器,通過this.$route訪問當(dāng)前路由。
動(dòng)態(tài)路由匹配
eg: 將不同id的用戶都指向User組件 const router = new Router({ routes: [ // 動(dòng)態(tài)路徑參數(shù),以冒號(hào)開頭 {path: "/user/:id", component: User} ] }) 多次路由如果渲染同個(gè)組件,組件會(huì)被復(fù)用,所以生命周期鉤子不會(huì)再調(diào)用,可以使用watch監(jiān)聽$route對(duì)象。 watch: { "$route": (to, from) {} }
通配符(*): path: "*" path: "user-*" 如果使用通配符,$route.params會(huì)自動(dòng)添加一個(gè)名為pathMatch參數(shù) // 給出一個(gè)路由 { path: "/user-*" } this.$router.push("/user-admin") this.$route.params.pathMatch // "admin" // 給出一個(gè)路由 { path: "*" } this.$router.push("/non-existing") this.$route.params.pathMatch // "/non-existing"
編程式導(dǎo)航
Vue實(shí)例內(nèi)部使用this.$router訪問 router.push(location, onComplete?, onAbort?) eg: // 字符串 router.push("home") // 對(duì)象 router.push({ path: "home" }) // 命名的路由,如果提供了path,params會(huì)被忽略 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方法,否則鉤子不會(huì)被resolved // next() 進(jìn)行下一個(gè)鉤子 // 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)航被確認(rèn)之前,同時(shí)在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,解析守衛(wèi)就被調(diào)用 全局后置鉤子: router.afterEach((to, from) => {}) 路由獨(dú)享的守衛(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) { // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用 // 不!能!獲取組件實(shí)例 `this` // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建 // 可以通過傳一個(gè)回調(diào)給 next來訪問組件實(shí)例。在導(dǎo)航被確認(rèn)的時(shí)候執(zhí)行回調(diào),并且把組件實(shí)例作為回調(diào)方法的參數(shù) next(vm => { // 通過 `vm` 訪問組件實(shí)例 }) }, beforeRouteUpdate (to, from, next) { // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用 // 舉例來說,對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候, // 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。 // 可以訪問組件實(shí)例 `this` }, beforeRouteLeave (to, from, next) { // 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用 // 可以訪問組件實(shí)例 `this` } }
路由元信息
meta: { requiresAuth: true } 訪問元信息: 路由是可以嵌套的,因此一個(gè)路由匹配成功后,可能匹配多個(gè)路由記錄 $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() } })
頁面滾動(dòng)
const router = new Router({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 期望滾動(dòng)到哪個(gè)的位置 return { x: 0, y: 0 } } })
路由懶加載
const Home = () => import("@/pages/home/Home") (resolve) => require(["pages/marketing-center/mission-medal/mission-rules/mission-rules"], resolve)
State、Getter、Mutation、Action、Module
為什么要用vuex: 當(dāng)多個(gè)組件共享狀態(tài)時(shí)(多個(gè)視圖依賴同一狀態(tài),不同視圖的行為需要變更同一狀態(tài)) vuex和單純的全局對(duì)象有兩點(diǎn)不同: 1.vuex的存儲(chǔ)是響應(yīng)式的,當(dāng)vue組件從store中讀取狀態(tài)時(shí),若store中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)得到高效更新。 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
就像計(jì)算屬性一樣,getter的返回值會(huì)根據(jù)它的依賴被緩存起來,且只有當(dāng)依賴值發(fā)生了改變才會(huì)被重新計(jì)算。 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í)返回一個(gè)函數(shù): getters: { getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } } 訪問時(shí)可以傳參數(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ù)雜時(shí),store對(duì)象會(huì)非常臃腫。 因此,vuex允許我們將store分割成模塊(module),每個(gè)模塊擁有自己的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)置對(duì)象)
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)建時(shí)間, Date對(duì)象: console.log("birth time: " + stat.birthtime); // 修改時(shí)間, Date對(duì)象: console.log("modified time: " + stat.mtime); } } })
stream
var fs = require("fs") // 打開一個(gè)流 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("用流寫二進(jìn)制數(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對(duì)象, // 獲得HTTP請(qǐng)求的method和url: console.log(request.method + ": " + request.url); // 將HTTP響應(yīng)200寫入response, 同時(shí)設(shè)置Content-Type: text/html: response.writeHead(200, {"Content-Type": "text/html"}); // 將HTTP響應(yīng)的HTML內(nèi)容寫入response: response.end("Hello world!
"); }); // 讓服務(wù)器監(jiān)聽8080端口: server.listen(8080);
web框架(koa2)
對(duì)http有封裝,使用Promise并配合async來實(shí)現(xiàn)異步。 // 導(dǎo)入koa,和koa 1.x不同,在koa2中,我們導(dǎo)入的是一個(gè)class,因此用大寫的Koa表示: const Koa = require("koa"); // 創(chuàng)建一個(gè)Koa對(duì)象表示web app本身: const app = new Koa() // 對(duì)于任何請(qǐng)求,app將調(diào)用該異步函數(shù)處理請(qǐng)求: app.use(async (ctx, next) => { await next(); ctx.response.type = "text/html"; ctx.response.body = "Hello, koa2!
"; }); // 在端口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 = `Hello, ${name}!
`; }); router.get("/", async (ctx, next) => { ctx.response.body = "Index
"; }); // add router middleware: app.use(router.routes()); app.listen(3000); console.log("app started at port 3000...");
處理post請(qǐng)求,獲取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"); //實(shí)現(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++; } } } });
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/114873.html
摘要:獲取的對(duì)象范圍方法獲取的是最終應(yīng)用在元素上的所有屬性對(duì)象即使沒有代碼,也會(huì)把默認(rèn)的祖宗八代都顯示出來而只能獲取元素屬性中的樣式。因此對(duì)于一個(gè)光禿禿的元素,方法返回對(duì)象中屬性值如果有就是據(jù)我測試不同環(huán)境結(jié)果可能有差異而就是。 花了很長時(shí)間整理的前端面試資源,喜歡請(qǐng)大家不要吝嗇star~ 別只收藏,點(diǎn)個(gè)贊,點(diǎn)個(gè)star再走哈~ 持續(xù)更新中……,可以關(guān)注下github 項(xiàng)目地址 https:...
摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語言和等其他語言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語言和Java、python等其他語言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...
摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語言和等其他語言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語言和Java、python等其他語言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...
摘要:元素的位置通過以及屬性進(jìn)行規(guī)定。表明請(qǐng)求被正常處理了。服務(wù)器返回的響應(yīng)報(bào)文包括協(xié)議版本狀態(tài)碼解釋狀態(tài)碼的原因短語響應(yīng)首部字段實(shí)體主體。瀏覽器接受響應(yīng),檢查里的狀態(tài)碼,并做出不同的處理方式。關(guān)于返回的狀態(tài)碼的具體說明看上個(gè)問題。 說明:簡答題沒有固定答案,以下給出的答案是從別處摘錄或自己總結(jié),有錯(cuò)之處歡迎指出。 html 篇 標(biāo)簽上title和alt屬性的區(qū)別是什么? alt是htm...
摘要:元素的位置通過以及屬性進(jìn)行規(guī)定。表明請(qǐng)求被正常處理了。服務(wù)器返回的響應(yīng)報(bào)文包括協(xié)議版本狀態(tài)碼解釋狀態(tài)碼的原因短語響應(yīng)首部字段實(shí)體主體。瀏覽器接受響應(yīng),檢查里的狀態(tài)碼,并做出不同的處理方式。關(guān)于返回的狀態(tài)碼的具體說明看上個(gè)問題。 說明:簡答題沒有固定答案,以下給出的答案是從別處摘錄或自己總結(jié),有錯(cuò)之處歡迎指出。 html 篇 標(biāo)簽上title和alt屬性的區(qū)別是什么? alt是htm...
閱讀 1675·2021-10-13 09:39
閱讀 2109·2021-09-07 10:20
閱讀 2690·2019-08-30 15:56
閱讀 2958·2019-08-30 15:56
閱讀 939·2019-08-30 15:55
閱讀 637·2019-08-30 15:46
閱讀 3504·2019-08-30 15:44
閱讀 2563·2019-08-30 11:15