前端巨無霸長文-持續更新
- 一,界面構建相關
- 1,瀏覽器渲染機制
- 瀏覽器渲染原理
- JS加載與執行機制
- defer 和async 屬性的區別
- 2,HTML
- HTML行內元素與塊級元素
- HTML5特性
- 標簽語意化
- 多媒體播放
- 新增表單控制元件
- 新增技術Webwork
- 新增技術Websocket
- 本地離線存盤localStorage
- 3,CSS
- 盒模型
- 引入樣式時,使用link和@import有什么區別
- CSS選擇器優先級
- 偽元素和偽類的區別
- CSS3特性
- 盒子陰影
- 新增選擇器
- 屬性選擇器:elem[property]
- 結構偽選擇器
- 偽元素選擇器
- 圓角
- 2D轉換
- 影片
- 3D轉換
- 4,常見頁面布局操作
- 三欄式布局
- float布局
- 絕對定位布局
- flex布局
- 水平垂直居中
- 定位 + 負margin
- 定位 + auto margin
- 定位 + transfrom
- 定位 + calc
- 通過flex
- CSS畫一個三角形和箭頭
- 超出內容顯示省略號
- 輪播圖的實作
- 二,JS相關
- JS基礎概念
- EventLoop事件回圈機制
- this指向
- 作用域鏈
- 詞法作用域
- 閉包
- new關鍵之的實作原理
- 原型以及原型鏈
- call方法實作原理
- 防抖節流
- JS演算法
- 冒泡排序法
- 三,前端框架相關
- 1,Vue
- 雙向資料系結原理
- 回應式原理
- 父子組件之間的傳值
- 父組件傳值給子組件
- 子組件傳值給父組件
- 非父子組件之間的傳值
- bus模式/總線模式
- vuex
- 生命周期
- $nextTick
- 四,其他知識總結
- 瀏覽器
- Cookie、Session、Token
- 常見瀏覽器所用內核
- 程式、行程、執行緒
- 資料通訊
一,界面構建相關
1,瀏覽器渲染機制
瀏覽器渲染原理
1,將HTML決議成DOM樹
2,將CSS決議成CSSOM樹
3,將DOM和CSSOM樹合并后生產Render樹(渲染樹);
4,Layout(布局),計算節點的位置;
5,Paint(繪制),將布局繪制在螢屏上;
注意:
重排即回流(reflow)和重繪(repaint)是不同的,只要改變元素的位置的操作就會觸發重排(例如:元素尺寸改變——邊距、填充、邊框、寬度和高度),位置不變只是樣式改變則只是觸發重繪(例如:改變元素的color、background、box-shadow等屬性)
特別地:display:none會觸發reflow,而visibility:hidden只會觸發repaint,因為沒有發現位置變化,

JS加載與執行機制
JavaScript 的加載、決議與執行會阻塞檔案的決議, 等 JavaScript 引擎運行完畢,瀏覽器再從中斷的地方恢復繼續決議檔案,
如果你想首屏渲染的越快,就越不應該在首屏就加載 JS 檔案,這就是建議將 script 標簽放在 body 標簽底部的原因,當然并不是說 script 標簽必須放在底部,因為你可以給 script 標簽添加 defer 或者 async 屬性,
defer 和async 屬性的區別
一圖勝千言

2,HTML
HTML行內元素與塊級元素
- HTML常見行內元素:img,a,b,span,strong,em,sub,sup,button,input,label,select,textarea
- HTML常見塊級元素:div,ul,ol,li,dl,dt,dd,h1-h6,p
- HTML行內元素與塊級元素的區別
· 行內元素設定:width,height,margin-top,margin-bottom,padding-top,padding-bottom無效,但是line-height有效,
· 行內元素不會獨占一行,塊級元素會獨占一行
· 可以通過display:block;或display:inline;或者display:inline-block改變元素型別
其中line-block使得元素與block幾乎一樣,但卻保留了inline不會獨占一行的特性
HTML5特性
標簽語意化
比如:article,footer,header,nav,section
1,提高了代碼的可讀性,便于維護和開發
2,更便于搜索引擎優化(SEO)
多媒體播放
音頻
<audio controls="controls">
<source src="demo.mp3" type="audio/mp3">
</audio>
視頻
<video width="320" height="240" controls="controls">
<source src="demo.mp4" type="video/mp4">
</video>
新增表單控制元件
<label>日期</label><input type="date"><br>
<label>時間</label><input type="time"><br>
<label>郵箱</label><input type="email"><br>
<label>搜索</label><input type="search"><br>
<label>網址url</label><input type="url"><br>
<label>顏色</label><input type="color"><br>
<label>范圍</label><input type="range">
新增技術Webwork
鋪墊:
(1)對于Chrome瀏覽器內部至少有6個執行緒負責向服務器發起請求獲取資源,此處稱之為:請求執行緒;另外還有一個執行緒負責繪制所有資源并且執行js程式,此處稱之為:UI主執行緒;問題就在于這個UI主執行緒既要繪制又要執行JS程式,因此當執行JS代碼的程序中會阻塞UI的繪制;
代碼示例:
正常運行UI主執行緒
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>按鈕1</button>
<script src="js/demo.js"></script>
<button>按鈕2</button>
</body>
</html>
效果是:先出現【按鈕1】五秒后出現【按鈕2】并且輸出console.log()列印陳述句
通過Webworker創建一個執行緒幫助UI主執行緒執行JS代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>按鈕1</button>
<script>
let worker = new Worker("js/demo.js")
</script>
<button>按鈕2</button>
</body>
</html>
效果是:同時出現【按鈕1】【按鈕2】然后輸出console.log()列印陳述句
js/demo.js
let startTime = new Date().getTime()
let endTime = null;
do {
endTime = new Date().getTime()
}while (endTime - startTime < 5000)
console.log("執行demo.js的5秒后")
注意:不同瀏覽器的渲染機制會有所不同,此處實驗使用的是chrome瀏覽器
新增技術Websocket
(1)Websoket傳輸資料的方式是全雙工的,通訊擁有更強的實時性
(2)由于低延遲,高及時的特性,多應用于多人協同的場景,
本地離線存盤localStorage
本地離線存盤,localStorage長期存盤資料,瀏覽器關閉后資料不會丟失;與sessionStorage相比,sessionStorage的資料在瀏覽器關閉后會自動洗掉,
3,CSS
盒模型
(1)標準盒模型:(box-sizing:content-box) width,height只包含content內容,因此padding進而boder不受height和width控制,所以當padding值>0時候會增大盒子大小,
(2)怪異盒模型:(box-sizing:border-box) width,height包含了content,padding,border,因此padding和border納入height,width控制的,

引入樣式時,使用link和@import有什么區別
(1)從屬關系的區別: @import是CSS提供的語法規則,只有匯入樣式表的作用;link是HTML提供的標簽,它不僅可以加載CSS檔案還可以定義RSS、rel連接屬性,引入網站圖示等,
(2)加載機制的區別:加載頁面時候,link標簽引入的CSS被同時加載;@import 引入的CSS需要在頁面加載完畢后再被加載,
(3)兼容性的區別,link標簽沒有兼容性問題,@import是CSS2.1才支持的語法,因此需要IE5+才能夠支持;
(4)DOM可控性區別可以通過JS操作DOM插入link標簽進而改變樣式;而@import匯入CSS樣式的方式無法通過DOM進行操作,
CSS選擇器優先級
ID 選擇器:如 #id{}
類選擇器:如 .class{}
屬性選擇器: 如 a[href="segmentfault.com"]{}
偽類選擇器: 如 :hover{}
偽元素選擇器: 如 ::before{}
標簽選擇器: 如 span{}
通配選擇器:如 *{}
!important (權重最高)>行內樣式 (權重為:1000)> ID 選擇器(權重為:100)> 類選擇器= 屬性選擇器= 偽類選擇器(權重為:10)> 標簽選擇器 = 偽元素選擇器(權重為1)
偽元素和偽類的區別
(1)偽元素用來創建一些不在檔案樹中的元素,并為七天假對應的樣式,使用::進行表示,但是由于在舊版的W3C標準規范并為對其進行特別區分,因此目前大多數瀏覽器都支持這兒兩種方式(:: 或者:)表示偽元素,常見::before、::after
(2)偽類用于為元素處于某種狀態下,對其添加對應樣式,常見 :hover、:focus
CSS3特性
盒子陰影
box-shadow: offset-x offset-y [blur [spread]] [color] [inset]
- box-shadow 屬性用于向盒子添加一個或多個陰影效果,
- offset-x:陰影的水平偏移量,正數向右偏移,負數向左偏移,
- offset-y:陰影的垂直偏移量,正數向下偏移,負數向上偏移,
- blur:陰影模糊度,不能取負數,
- spread:陰影大小,正數陰影擴大(陰影大小大于盒子大小),負數陰影縮小(陰影大小小于盒子大小),0陰影與盒子同等大小,
- inset:表示添加內陰影,默認為外陰影,
新增選擇器
屬性選擇器:elem[property]
結構偽選擇器
(1)elem:nth-child(n)選擇父元素下n個子元素,并且這個元素的標簽名稱為elem,n可以接受具體的數字、值(odd和even)、公式(作為公司的時候n是從0開始的),
(2)elem:nth-last-child(n)作用同上,區別在于該偽類從后開始查找
(3)elem:last-child選父元素中飯中最后一個子元素
(4)elem:first-child選中父元素中第一個子元素
(5)elem:only-child如果elem是父元素下唯一的子元素,則選中之
(7)elem:nth-of-type(n)選擇父元素下第n個elem型別元素,n可以接受具體的數值,也可以接受函式
(8)elem:first-of-type選擇父元素下第一個elem型別元素
(9)elem:last-of-type擇父元素下最后一個elem型別元素
(10)elem:only-of-type選擇父元素下只有一個elem型別元素
(11)elem:empty選中不包含子元素和內容的elem型別元素
(12)not(elem)選擇非 elem 元素的每個元素
(13)checked 單選框或復選框被選中
偽元素選擇器
(1)::before 在元素內部前面插入內容
(2)::after 在元素內部后面插入內容
注意
- before和after必須有content屬性
- before在內容的前面,after內容的后面
- before和after創建的是一個元素,但是在DOM里面是看不見的元素因此稱之為偽元素,這個元素屬于行內元素,定義寬高的時候必須設定box-sizing:block或者box-sizing:inline-block
- 偽元素和標簽選擇器一樣權重為1
圓角
border-radius:8px
2D轉換
(1) 2D 移動: transform: translate(x,y); 單位px
(2)2D 旋轉: transform:rotate(0deg)l
(3)轉換中心點(縮放與旋轉都有影響):transform-origin: x y;
重點:
- 注意后面的引數x和y用空格隔開
- x y 默認轉換中心電視元素的中心點(50% 50%) 或者(center center)
- x y 可以是像素數值,或者方位名詞:top bottom left right center
(4)2D 縮放: transform:scale( x y) ;
重點: - 沒有單位,x y 指的寬度和高度的倍數
(5)過度:transition: all 0.5s;
重點: - 語法transition: property(屬性) duration(過度時長) timing-function(過度方法) delay(延遲時長);
影片
(1)影片基本使用步驟:
- 定義影片
- 使用影片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="animation-box"></div>
</body>
<style>
/*定義影片*/
@keyframes move {
0%{
transform: translate(0px,0px);
}
100%{
transform: translate(1000px,0px);
}
}
.animation-box{
height: 100px;
width: 100px;
background-color: pink;
/*使用影片*/
animation-name: move;
animation-duration: 2s;
animation-direction: alternate;
animation-iteration-count: infinite;
}
</style>
</html>
(2)影片常用屬性:

(3)暫停影片:animation-paly-state:paused
(4)影片簡寫屬性:
animation:影片名稱 持續事件 運動曲線 何時開始 播放次數 是否反方向 影片起始或者結束的狀態;
animation:name 5s linear 2s infinite alternate;
- 簡寫屬性里面不包含animation-play-state
- 暫停影片:animation-play-state:paused;經常和滑鼠經過配合使用
- 想要影片偶組回來,而不是直接跳回來:animation-direction:alternate;
- 影片結束后,停在結束的位置:animation-fill-mode:forwords;
3D轉換
(1)轉換
- transform:translateX(100px):在X軸移動
- transform:translateY(100px):在Y軸移動
- transform:translateZ(100px):在Z軸移動(垂直于螢屏)配合透視來觀察
- transform:translate3d(x,y,z):其中x,y,z指的是要移動軸的方向距離
(2)透視:perspective: 100px;
注意:
- 透視需要寫到被觀察元素的父元素上
- 透視就是模擬視距,值越小,代表越近,看的越大
(3)3d旋轉
- transform:rotate(45deg):沿著x軸旋轉45度
- transform:rotate(45deg):沿著y軸旋轉45度
- transform:rotate(45deg):沿著z軸旋轉45度
- transform:rotate3d(x,y,z,deg):x,y,z組成矢量方向,deg為旋轉角度
左手螺旋法則,拇指指向旋轉軸的正方向,手指方向為旋轉方向,
x軸正方向:→
y軸正方向:↓
z軸正方向:垂直螢屏向外
4,常見頁面布局操作
三欄式布局
float布局

絕對定位布局

flex布局

水平垂直居中
定位 + 負margin

定位 + auto margin

定位 + transfrom

定位 + calc

通過flex

CSS畫一個三角形和箭頭
三角形的原理:
相鄰邊框連接處是均分的,將其他邊顏色值設定為transparent透明即可實作三角形的效果;


超出內容顯示省略號
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
輪播圖的實作
以下的實作方式不是最優的,但是這里通過CSS最大限度的對其進行實作,剩余的自動播放與互動還是用回了JS,因此做復雜了,建議主要使用JS進行實作,
- labell標簽可以通過for="元素id"屬性系結對應的input元素,進而使得點擊label標簽即可觸發checked的變動,
- 用到CSS “~” 這個符號的選擇器,該符號可以選擇其后同級元素的層級元素,搭配:checked這個選擇器,即可使得當某個radio選項被選中時候,同級的 ul下所有li同時向左移動,在此之上加上transition過度效果既可以實作點擊選項切換圖片的效果,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="swiper">
<ul class="sliders" onm ouseover="handleMouseover()" onm ouseout="handleMouseout()">
<input type="radio" id="control-1" name="slider-radio" checked>
<input type="radio" id="control-2" name="slider-radio">
<input type="radio" id="control-3" name="slider-radio">
<div class="label-box">
<label for="control-1" index="1"></label>
<label for="control-2" index="2"></label>
<label for="control-3" index="3"></label>
</div>
<li class="slider">1</li>
<li class="slider">2</li>
<li class="slider">3</li>
</ul>
</div>
<style>
input[type="radio"]{
position: relative;
z-index: 100;
display: none;
}
.swiper{
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.sliders{
position: relative;
height: 300px;
width: 400px;
background-color: gray;
padding: 0;
margin: 0;
overflow: hidden;
}
.slider{
position: absolute;
list-style: none;
padding:0;
margin: 0;
height: inherit;
width: inherit;
display: flex;
justify-content: center;
align-items: center;
color: aliceblue;
font-size: 100px;
transition: all 0.5s;
}
.slider:nth-of-type(1){
background-color: #ffb700;
}
.slider:nth-of-type(2){
left:100%;
background-color: #ff0073;
}
.slider:nth-of-type(3){
left: 200%;
background-color: #0066ff;
}
.label-box{
position: absolute;
bottom: 10px;
width: 100%;
text-align: center;
z-index: 100;
}
.label-box>label{
display: inline-block;
height: 10px;
width: 10px;
border:2px solid #ffffff;
border-radius: 50%;
background-color: aliceblue;
cursor: pointer;
}
input[type="radio"]:nth-child(1):checked ~ .label-box label:nth-child(1){
background-color: #232323;
}
input[type="radio"]:nth-child(2):checked ~ .label-box label:nth-child(2){
background-color: #232323;
}
input[type="radio"]:nth-child(3):checked ~ .label-box label:nth-child(3){
background-color: #232323;
}
input[type="radio"]:nth-child(1):checked ~ .slider{
transform: translateX(0)
}
input[type="radio"]:nth-child(2):checked ~ .slider {
transform: translateX(-100%)
}
input[type="radio"]:nth-child(3):checked ~ .slider {
transform: translateX(-200%)
}
</style>
<script>
let slides = document.getElementsByTagName("input")
let i = 1
let timer
function startTimeout(){
timer = setInterval(function () {
if (i>=slides.length){
i = 0
}
slides[i].checked = true
i++
},2000)
}
startTimeout()
function handleMouseover(){
clearTimeout(timer)
}
function handleMouseout (){
startTimeout()
}
//這里是為了使得點擊按鈕后,使得i的值與輪播圖此時輪播到第幾張進行對應,
function setCurrentIndex(e){
i = parseInt(e.target.getAttribute("index"))
}
let labels = document.getElementsByTagName("label")
for (let k = 0 ;k<labels.length;k++){
labels[k].addEventListener("click",setCurrentIndex)
}
</script>
</body>
</html>
二,JS相關
JS基礎概念
EventLoop事件回圈機制
Event Loop 是一個很重要的概念,指的是計算機系統的一種運行機制,
JavaScript語言就采用這種機制,來解決單執行緒運行帶來的一些問題,
JS通過事件回圈機制已達到非阻塞的效果,當遇到異步任務我們現將其掛起,直到同步代碼執行完畢后,再去任務佇列中去執行異步任務(先執行微任務,后指向宏任務)
微任務:promise …
宏任務:setTimeout、setInterval …
this指向
this的指向是動態進行系結的,不受作用域的限制,
方法中的this指向問題可以通過call,apply,bind指向,call和apply的區別在于傳參的形式不同,bind則是系結了不執行罷了,
凡是通過 obj.func()進行呼叫的,func中的this指向的就是呼叫者obj如果被呼叫的函式為箭頭函式則另當別論,箭頭函式沒有this,因此箭頭函式中的this靜態的,它指向它的詞法作用域中的this
嵌套函式和普通函式,僅僅作為函式進行呼叫,而非通過物件進行呼叫時候,通常指向的是全域物件,嚴格模式下為undefined
作用域鏈
- JS沒有塊作用域,只有全域作用域和區域作用域,區域作用域只存在于function中,
- 直到ES6出現了let和const才緩解了塊作用域的問題,同時伴隨則暫時性死區的問題,
- 當我們訪問一個變數的時候,首先會在自身所在的作用域進行查詢,如果沒有則往上進行查找直到查找到全域作用域時,仍然無法找到,則會報錯,不存在嵌套函式的的情況下只有兩層作用域,一個是全域作用域,一個是函式作用域,存在嵌套函式的情況下作用域大于等于三層,
詞法作用域
詞法作用域指的是宣告時所在作用域,而非運行時,
閉包
一個函式和對其周圍狀態(lexical environment,詞法環境)的參考捆綁在一起(或者說函式被參考包圍),這樣的組合就是閉包,
閉包是由函式以及宣告該函式的詞法環境組合而成的,該環境包含了這個閉包創建時作用域內的任何區域變數,
在回圈中創建閉包是常見第一種錯誤使用方式,解決這個問題可以通過使用更多的閉包或者使用let進行宣告回圈變數,
new關鍵之的實作原理
new 關鍵字做了什么動作
- 創建了一個物件
let obj - 將這個新創建的物件的原型指向建構式的原型上
obj.__proto__ = constructor.prototype - 呼叫建構式對這個物件進行初始化
constructor.apply(obj,arg)
function myNew (constructor,...arg){
let obj = {}//創建一個物件
obj.__proto__ = constructor.prototype //將新創建的物件的原型指向建構式的原型
constructor.apply(obj,arg)//呼叫建構式初始化物件
return obj//將物件回傳
}
原型以及原型鏈
每個物件都有一個私有屬性(proto)指向它的建構式的原型物件(prototype)該(prototype)原型物件也有自己私有屬性(proto)指向它的建構式的原型物件(prototype),層層向上知道一個物件的原型物件為null,根據定義null沒有原型,
基于原型鏈的繼承,物件可以訪問到原型鏈上的方法和屬性,
call方法實作原理
Function.prototype.myCall = function(){
let caller = this//這里相當于fun.call(obj,...arg)中fun
let targetObj = arguments[0]//這里相當于fun.call(obj,...arg)中的第一個引數obj
let otherArgs = []//這里相當于fun.call(obj,...arg)中的除了第一個引數的所有引數的集合...arg
for (let i = 1 ;i<arguments.length;i++){
otherArgs.push(arguments[i])
}
targetObj.caller = caller
let res = targetObj.caller(...otherArgs)//這里完成了this的動態系結
delete caller
return res
}
console.log([].filter.myCall([1,2,6,2,3,5],function (item){
return item >3
}))
防抖節流
/*防抖函式*/
//事件連續觸發多次,只執行最后一次觸發,并且停止觸發事件后的timing秒才會執行
function debounce(fun,timing){
let timer//用于記錄定時
return function (){
clearTimeout(timer)//清除定時
timer = setTimeout(function (){
fun()
},timing)
}
}
/*節流函式*/
//事件觸發多次,只在一定時間內執行一次
function throttle(fn,timing){
let trigger//是否觸發的判斷值
return function (){
if (trigger) return //如果已經觸發過了直接回傳,不再往下執行
trigger = true //如果沒有觸發過,往下執行觸發,并且把該狀態改為觸發
fn()
//并且通過定時器,設定timing秒后才將狀態變為未觸發,即timing秒后才可以再次觸發
setTimeout(function (){
trigger = false
},timing)
}
}
JS演算法
冒泡排序法
let arr = [4,9,10,22,7,3,2]
//冒泡排序法
function bubbleSort(arr){
let temp
for (let i = 0;i<arr.length;i++){
for(let j=0;j<arr.length-1-i;j++){
if (arr[j+1]<arr[j]){
temp = arr[j+1]
arr[j+1] = arr[j]
arr[j] = temp
}
}
console.log(arr.join("-"))
}
return arr
}
bubbleSort(arr)
三,前端框架相關
1,Vue
雙向資料系結原理
v-model其實是v-on和input事件監聽的一個語法糖,
v-model原理:通過v-on實作了對資料物件data的監聽,通過input事件監聽,把輸入框中的值更新到資料物件data,這樣一來就實作了雙向資料系結,
回應式原理
通過Object.defineProperty來實作監聽資料的改變和讀取(屬性中的getter和setter方法) 實作資料劫持,
父子組件之間的傳值
- 父組件參考子組件的時候直接在組件標簽上定義標簽屬性,如果需要使用data中的值可以使用v-bind進行系結
//此處title為傳遞給子組件的值
....
<Demo v-bind:title="title" @myEvent="listenSun"></Demo>
....
- 子組件通過porps屬性進行接受父組件傳遞過來的值
....
//定義的是傳遞過來的數值型別
props:{
title: String
}
....
父組件傳值給子組件
- 子組件通過this.$emit(“eventName”,",message")進行觸發自定義事件
<template>
<div class="demo-layout">
<h1 v-on:click="handleClick">點擊這里觸發/h1>
</div>
</template>
....
methods:{
handleClick: function (){
this.$emit("myEvent","message")//這個message就是傳遞給父組件的值
}
}
....
- 父組件通過v-on:eventName=“handleEventName” 對其進行監聽
<template
<div id="app">
<Demo v-bind:title="title" @myEvent="listenSun"></Demo>
</div>
</template>
....
methods: {
listenSun: function (message){//這里的message就是子組件傳遞過來的值
....
}
}
}
....
- handleEventName(message){} 可以接受到傳遞過來的message
子組件傳值給父組件
非父子組件之間的傳值
bus模式/總線模式
- 首先在Vue建構式的原型鏈上掛載一個Vue的實體物件
vuex
- 安裝
npm install vuex --save
- 在src目錄下創建 store目錄,同時創建一個index.js檔案
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
export default new Vuex.Store({
//用于存放全域的資料
state:{
num:0
},
//相當于組件中計算屬性,省去在每個組件使用計算屬性的操作,
getters:{
getNum(state){
return state.num
}
},
//vuex推薦改變sate中的資料在此處進行.觸發需要使用$store.commit("mutationsName")
mutations:{
increaseNum(state){
state.num++
}
},
//相當于可以處理異步的mutation.觸發需要使用$store.dispatch("mutationsName")
actions:{
asyncIncreaseNum(context){
setTimeout(()=>{
context.commit('increaseNum')
},1000)
}
},
modules:{}
})
- 在全域中引入vuex
import Vue from 'vue'
import App from './App.vue'
import store from '@/store'
Vue.config.productionTip = false
Vue.prototype.bus = new Vue()
new Vue({
store,//全域注冊
render: h => h(App),
}).$mount('#app')
- 在組件中使用vuex
<template>
<div class="count-layout">
<h1>{{this.$store.getters.getNum}}</h1>
<h1>{{this.$store.state.num}}</h1>
<input type="button" value="+1" @click="handleClickAdd">
<input type="button" value="async+1" @click="handleAsyncClickAdd">
</div>
</template>
<script>
export default {
name: "Count",
methods: {
handleClickAdd() {
this.$store.commit("increaseNum")
},
handleAsyncClickAdd(){
this.$store.dispatch("asyncIncreaseNum")
}
}
}
</script>
<style scoped>
</style>
檔案:main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
Vue.prototype.bus = new Vue()
new Vue({
render: h => h(App),
}).$mount('#app')
- 一個組件使用this.bus.$emit(“eventName”,“message”)
<template>
<div class="demo-layout">
<h1 v-on:click="handleClickSendBus">點擊此處觸發</h1>
</div>
</template>
....
methods:{
handleClickSendBus: function (){
this.bus.$emit("busEvent","busMessage")
}
}
....
- 另一個組件使用this.bus.$on(“eventName”,“message”)
....
created() {
this.bus.$on("busEvent",message => {//此處的message就是其他組件傳遞過來的值
....
})
}
....
生命周期
beforeCreate:data和method還沒有創建,在這個宣告周期鉤子函式上不能使用data;
created:可以訪問里面的資料物件data和方法物件methods;
beforeMount:el實力和data都初始化了,但未掛載到DOM;
mounted:vue實體掛載到DOM了,此時可以對DOM進行操作;
beforeupdated:回應式資料更新時呼叫,此時并未完成DOM重新渲染;
updated:虛擬DOM重新渲染和打補丁之后呼叫,組成新的DOM已經更新,避免在這個鉤子函式中操作資料,防止死回圈;
beforeDestroy:實體銷毀前呼叫,實體還可以用,this能獲取到實體,常用于銷毀定時器,解綁事件;
destroyed:實體銷毀后呼叫,呼叫后所有事件監聽器會被移除,所有的子實體都會被銷毀;
$nextTick
在Vue中資料發生改變,Dom不是立即更新的,為了準確的獲取到最新的Dom我們可以使用$nextTick
四,其他知識總結
瀏覽器
Cookie、Session、Token
(1)Cookie:客戶端訪問服務器,服務器為了識別用戶創建Session,將SessionId保存到Cookie中發送給客戶端,客戶端將其存盤在瀏覽器中,當再次訪問服務器的時候會自動將Cookie加入到請求,隨著請求一并傳遞到服務器端,
(2)Session是存盤在服務器端的,服務器端通過決議Cookie獲取到對應的SessionId來找到對應的Session,Session是依賴Cookie的
(3)Token由三部分組成:uid(用戶唯一標識)、time(時間戳)、sign(簽名),相當于一個令牌,用戶資訊存盤到Token中,服務器接收到Token解密后才識別到用戶資訊,與Cookie不同的,發送需要開發者手動添加,
常見瀏覽器所用內核
(1)IE瀏覽器內核:Trident內核俗稱IE內核;
(2)Chrome瀏覽器內核:以前是Webkit內核現在是Blink內核,
(3)Safari瀏覽器內核:Webkit內核
(4)Firefox瀏覽器內核:Gecko內核,俗稱Firefox內核
(5)Opera瀏覽器內核:起初是自己的Presto內核,后再加入了谷歌大軍,從Webkit又到了Blink;
(6)360瀏覽器,獵豹瀏覽器內核:IE+Chrome雙內核
(7)搜狗,遨游,QQ瀏覽器內核:Trident(兼容模式)+Webkit(高速模式)
(8)百度瀏覽器、世界之窗內核:IE內核
(9)2345瀏覽器內核:IE+Chrome雙內核
(10)UC瀏覽器內核:眾口不一,UC自稱自己研發U3內核,但是還是基于Webkit和Trident,還有說是基于火狐內核的,
程式、行程、執行緒
程式的概念:通俗的講,程式是存盤在磁盤中運行在cpu的代碼,例如c:/demo.js
行程的概念:通俗的講,將程式調入記憶體中并分配一定的空間,在記憶體中的程式為記憶體,
執行緒:通俗的講,行程中包含多個執行緒,執行緒就好比如一個工廠中的其中一條流水線,
資料通訊
(1)單工通訊:收發埠固定,一個固定為發送埠,一個固定為接受埠,例如遙控器,
(2)半雙工通訊:兩端都具備發送器和接收器,但同一時刻只能發送或只能接收資料的傳輸方式,由于這種方式要頻繁變換信道方向,故效率低,但可以節約傳輸線路,例如無線對講機
(3)全雙工通訊:發送資料的同時也能夠接收資料,兩者同步進行,例如:打電話,說話的同時依然能夠聽到對方的聲音,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/312149.html
標籤:其他
上一篇:?沒有你,我不會那么光彩奪目?
