tml的主體結構
標簽的分類
標簽的關系
sublime快捷鍵
單標簽
雙標簽
路徑
超鏈接額外知識運用
錨點
空連接
超鏈接的優化寫法 寫在head標簽中
特殊標記符
列表
<!doctype html><html><head>
單標簽
<!doctype html>
雙標簽
<head></head>
包含(嵌套關系、父子關系)
<head>
并列
<head></head><body></body>
快捷鍵 | 作用 |
---|---|
html:xt + tab | html4.01模板【新版本可能失效】 |
html + tab | html5模板 |
tab | 補全標簽 |
ctrl + shift + d | 快速復制一行 |
ctrl + shift + k | 快速刪除一行 |
ctrl + 鼠標左鍵單擊 | 集體輸入 |
ctrl + h | 查找替換 |
ctrl + f | 查找 |
ctrl + / | 注釋 |
ctrl + L | 快速選中當前行 |
ctrl + shift + ↑(↓) | 代碼的快速上移和下移 |
<!-- --> 注釋標簽<br /> 換行標簽<hr /> 水平線標簽<img src="logo.gif" alt="logo" title="這是淘寶的logo" width="200" height="100" />圖片標簽
<p></p> 段落標簽<h1></h1> 標題標簽 h1 - h6<font></font> 文本標簽<strong></strong> 文本加粗標簽,有語音加強<b></b> 文本加粗標簽<em></em> 文字傾斜,有語音加強<i></i> 文字傾斜<del></del> 刪除線,有語音加強<s></s> 刪除線<ins></ins> 下劃線,有語音加強<u></u> 下劃線<a title="百度" target="_blank">百度</a> 超鏈接
相對路徑
同一個目錄下直接寫文件的名稱就可以
文件和圖片在下一級目錄中,需要文件夾名稱 + \ + 文件名稱
圖片在上一級目錄中 ../ + 文件名稱
圖片在上一級的其它文件夾中 ../ + 文件夾名稱 + 文件名稱
總結:找到下級目錄使用/,找到上一級目錄使用../
絕對路徑
從盤符中開始的,這種路徑不能使用!因為項目最后都要移動,文件的路徑都是會變的。如:c:\baidu\logo.jpg
錨點
1.設置一個錨點 設置一個id
<div id="top"></div>
2.超鏈接到錨點
<a href="#top"></a>
空連接
<a href="#"></a>
超鏈接的優化寫法 寫在head標簽中
<base targer="_blank">
讓所有的超鏈接都是從新窗口中打開
空格 | |
---|---|
< | < |
> | > |
? | © |
更多信息請查閱
無序列表
<ul type="disc">
類型:disc 默認小黑點 circle 空心小圓點 square 小方塊
有序列表
<ol type="A" start="C">
類型:a A 字母順序 i I羅馬順序 1數字 start 表示開始的位置
自定義列表
<dl>
解析HTML,生成DOM樹,解析CSS,生成CSSOM樹
將DOM樹和CSSOM樹結合,生成渲染樹(Render Tree)
Layout(回流):根據生成的渲染樹,進行回流(Layout),得到節點的幾何信息(位置,大小)
Painting(重繪):根據渲染樹以及回流得到的幾何信息,得到節點的絕對像素
Display:將像素發送給GPU,展示在頁面上
表示臨時響應并需要請求者繼續執行操作的狀態代碼
表示成功處理了請求的狀態碼。
例:200 – 服務器成功返回網頁
表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向
例:
301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應時,會自動將請求者轉到新位置。
302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求。
304 (未修改) 自從上次請求后,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。
例:404 – 請求的網頁不存在
這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。
例:
500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。
503 (服務不可用) 服務器目前無法使用(由于超載或停機維護)。 通常,這只是暫時狀態。
服務器解析 HTTP1.1 的請求時,必須不斷地讀入字節,直到遇到分隔符 CRLF 為止。而解析 HTTP2 的請求就不用這么麻煩,因為 HTTP2 是基于幀的協議,每個幀都有表示幀長度的字段。
HTTP2 提供了首部壓縮功能。多請求請求時,有很多消息頭都是重復的。如果可以把相同的首部存儲起來,僅發送它們之間不同的部分,就可以節省不少的流量,加快請求的時間。
HTTP/2 在客戶端和服務器端使用“首部表”來跟蹤和存儲之前發送的鍵-值對,對于相同的數據,不再通過每次請求和響應發送。如果服務器收到了請求,它會照樣創建一張表。 當客戶端發送下一個請求的時候,如果首部相同,它可以直接發送這樣的首部塊:服務器會查找先前建立的表格,并把這些數字還原成索引對應的完整首部。
HTTP2 可以對比較緊急的請求設置一個較高的優先級,服務器在收到這樣的請求后,可以優先處理。
由于一個 TCP 連接流量帶寬(根據客戶端到服務器的網絡帶寬而定)是固定的,當有多個請求并發時,一個請求占的流量多,另一個請求占的流量就會少。流量控制可以對不同的流的流量進行精確控制。
HTTP2 新增的一個強大的新功能,就是服務器可以對一個客戶端請求發送多個響應。換句話說,除了對最初請求的響應外,服務器還可以額外向客戶端推送資源,而無需客戶端明確地請求。
措施:
1、驗證 HTTP Referer 字段
2、添加token驗證
利用的是用戶對惡意網站的權限,攻擊者會在用戶瀏覽某個網站時,通過偽裝成一個受信任的網站發送請求,CSRF 通過利用用戶的身份信息,從而讓用戶無意識地執行惡意操作。這些操作通常是由第三方發起的,而用戶并不知情。
措施:
1、輸入過濾
2、輸出轉義
3、使用 HttpOnly Cookie
引擎優化。是一種方式:利用搜索引擎的規則提高網站在有關搜索引擎內的自然排名。
1、SSR服務器渲染
2、預渲染prerender-spa-plugin
3、的title、description、keywords
4、化的HTML代碼,符合W3C規范
5、飾性圖片必須加alt
6、外鏈
7、向各大搜索引擎提交收錄自己的站點
8、少用iframe:iframe中的內容是不會被抓取到的
先創建XHR對象即XMLHttpRequest()
然后open準備發送,open中有三個參數一是提交方式get和post,二是接口地址,三是同步和異步
第三步是用send發送
第四步再發送的過程中通過onreadystatechange來監聽接收的回調函數,可以通過判斷readyState==4和status==200來判斷是否成功返回,然后通過responseText接收成功返回的數據
push,pop,unshift,shift,splice,join,concat,forEach,filter,map,sort,some,every
第一種:利用ES6的set來實現 例如:[...new Set(arr)]
第二種:借用臨時對象的方式
JS事件代理就是通過給父級元素(例如:ul)綁定事件,不給子級元素(例如:li)綁定事件,然后當點擊子級元素時,通過事件冒泡機制在其綁定的父元素上觸發事件處理函數,主要目的是為了提升性能,因為我不用給每個子級元素綁定事件,只給父級元素綁定一次就好了,在原生js里面是通過event對象的targe屬性實現
構造函數就是一個普通的函數,創建方式和普通函數沒有區別,不同的是構造函數習慣上首字母大寫。另外就是調用方式的不同,普通函數是直接調用,而構造函數需要使用new關鍵字來調用。
每當定義一個函數數據類型(普通函數、類)時候,都會天生自帶一個prototype屬性,這個屬性指向函數的原型對象,并且這個屬性是一個對象數據類型的值。
當我們訪問對象的一個屬性或方法時,它會先在對象自身中尋找,如果有則直接使用,如果沒有則會去原型對象中尋找,如果找到則直接使用。如果沒有則去原型的原型中尋找,直到找到Object對象的原型,Object對象的原型沒有原型,如果在Object原型中依然沒有找到,則返回undefined。
淺拷貝可以理解為改變一個對象屬性值,另一個對象屬性也會發生改變,即互相影響, 對象深拷貝即就是說改變一個對象屬性,另一個對象屬性值不會發生改變,可以通過多種方法來實現對象深拷貝,
淺拷貝方法:
深拷貝方法:
核心思想:引用數據類型是有基本數據類型構成的,并且,基本數據類型是不存在深淺拷貝這一說的,那么我們只需要將引用數據類型的每一層次的基本數據類型賦值,并遍歷到最深處的基本數據并賦值就可以完成深拷貝。
JS原生綁定事件主要為三種:
一是html事件處理程序
例如:點我
二是DOM0級事件處理程序
例如:var btn=document.getElementById(‘id元素’)
btn.onclick=function() {
//要處理的事件邏輯
}
三是DOM2級事件處理程序
例如: var btn=document.getElementById(‘id元素’)
//綁定事件
btn.addEventListener(‘click’,綁定的事件處理函數名,false)
//移除事件
btn.removeEventListener(‘click’,要移除的事件處理函數名,false)
== 用于比較兩者是否相等,忽略數據類型。
=== 用于更嚴謹的比較,值和值的數據類型都需要同時比較。
定位方式:普通流 (normal flow)、浮動 (float)、絕對定位 (absolute positioning)
BFC 即 Block Formatting Contexts (塊級格式化上下文):具有 BFC 特性的元素可以看作是隔離了的獨立容器,容器里面的元素不會在布局上影響到外面的元素,并且 BFC 具有普通容器所沒有的一些特性。
要元素滿足下面任一條件即可觸發 BFC 特性:
浮動元素:float 除 none 以外的值
絕對定位元素:position (absolute、fixed)
display 為 inline-block、table-cells、flex
overflow 除了 visible 以外的值 (hidden、auto、scroll)
BFC特性:
同一個 BFC 下外邊距會發生折疊
BFC 可以包含浮動的元素(清除浮動)
BFC 可以阻止元素被浮動元素覆蓋
清除浮動解決的方法有很多,主要目的是讓父級元素有高度
方法一:給父級元素設置絕對定位:position:absolute
方法二:給父級元素設置overflow:hidden;
方法三:通過偽對象來實現
盒模型其實就是瀏覽器把一個個標簽都看一個形象中的盒子,那每個盒子(即標簽)都會有內容(width,height),邊框(border),以及內容和邊框中間的縫隙(即內間距padding),還有盒子與盒子之間的外間距(即margin)
盒模型包括兩種:IE盒模型和w3c標準盒模型
IE盒模型總寬度即就是width寬度=border+padding+內容寬度
標準盒模型總寬度=border+padding+width
那如何在IE盒模型寬度和標準盒模型總寬度之間切換呢,可以通過box-sizing:border-box或設置成content-box來切換
其中:box-sizing:border-box //IE盒模型
box-sizing:content-box //w3c盒模型、
rem和em都是相對單位,主要參考的標簽不同:
rem是相對于根字號,即相對于標簽的font-size實現的,瀏覽器默認字號是font-size:16px
em:是相對于父元素標簽的字號,和百分比%類似,%也是相對于父級的,只不過是%相對于父級寬度的,而em相對于父級字號的
百分比是相對于父元素標簽的寬度和高度
vw和vh分別相對于屏幕寬度和屏幕高度的,1vw相當于屏幕寬度的1%,100vw相當于滿屏寬度100%,
定位:
flex布局: display: flex; justify-content: center; align-items: center;
在HTML中,每個元素都可以理解成一個盒子,在瀏覽器解析過程中,會涉及到回流與重繪:
回流:布局引擎會根據各種樣式計算每個盒子在頁面上的大小與位置
重繪:當計算好盒模型的位置、大小及其他屬性后,瀏覽器根據每個盒子特性進行繪制
防抖和節流都是為了解決短時間內大量觸發某函數而導致的性能問題,比如觸發頻率過高導致的響應速度跟不上觸發頻率,出現延遲,假死或卡頓的現象
防抖:在事件被觸發n秒后再執行回調函數,如果在這n秒內又被觸發,則重新計時。
節流:規定一個單位時間,在這個單位時間內,只能有一次觸發事件的回調函數執行,如果在同一個單位時間內某事件被觸發多次,只有一次能生效。
防抖和節流的區別:
-- 效果:
函數防抖是某一段時間內只執行一次;而函數節流是間隔時間執行,不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數。
-- 原理:
防抖是維護一個計時器,規定在delay時間后觸發函數,但是在delay時間內再次觸發的話,都會清除當前的 timer 然后重新設置超時調用,即重新計時。這樣一來,只有最后一次操作能被觸發。
節流是通過判斷是否到達一定時間來觸發函數,若沒到規定時間則使用計時器延后,而下一次事件則會重新設定計時器。
閉包說的通俗一點就是打通了一條在函數外部訪問函數內部作用域的通道。正常情況下函數外部是訪問不到函數內部作用域變量的,
表象判斷是不是閉包:函數嵌套函數,內部函數被return 內部函數調用外層函數的局部變量
優點:可以隔離作用域,不造成全局污染
缺點:由于閉包長期駐留內存,則長期這樣會導致內存泄露
如何解決內存泄露:將暴露全外部的閉包變量置為null
適用場景:封裝組件,for循環和定時器結合使用,for循環和dom事件結合.可以在性能優化的過程中,節流防抖函數的使用,導航欄獲取下標的使用
基于ajax同源策略,因為安全的考慮,ajax不允許訪問不同域名下的資源
只存在前后端訪問,后端訪問后端不存在跨域問題。
產生跨域的情況有:不同協議,不同域名,不同端口以及域名和ip地址的訪問都會產生跨域。
解決:
一、是jsonp
jsonp實現原理:主要是利用動態創建script標簽請求后端接口地址,然后傳遞callback參數,后端接收callback,后端經過數據處理,返回callback函數調用的形式,callback中的參數就是json
二、 是代理(前端代理和后端代理)
前端代理我在vue中主要是通過vue腳手架中的config中的index文件來配置的,其中有個proxyTable來配置跨域的
三、是CORS
CORS全稱叫跨域資源共享,主要是后臺工程師設置后端代碼來達到前端跨域請求的
vuex是一個狀態管理工具,主要解決大中型復雜項目的數據共享問題,主要包括state,actions,mutations,getters和modules 5個要素,
主要流程:組件通過dispatch到 actions,actions是異步操作,再actions中通過commit到mutations,mutations再通過邏輯操作改變state,從而同步到組件,更新其數據狀態。
getters相當于組件的計算屬性對,組件中獲取到的數據做提前處理的.再說到輔助函數的作用。
因為vuex中的state是存儲在內存中的,一刷新就沒了,例如登錄狀態,常見解決方案有:
第一種:利用H5的本地存儲(localStorage,sessionStorage)
第二種:利用第三方封裝好的插件,例如:vuex-persistedstate
第三種:使用vue-cookie插件來做存儲
同步即sync,形象的說就是代碼一行行執行,前面代碼和請求沒有執行完,后面的代碼和請求就不會被執行
異步:即async,形象的說就是代碼可以在當前程序沒有執行完,也可以執行后面的代碼
異步解決方案主要有:
回調地獄:為了實現某些邏輯經常會寫出層層嵌套的回調函數,如果嵌套過多,會極大影響代碼可讀性和邏輯,這種情況也被成為回調地獄
promise的狀態改變一次以后就不會再改變,鏈式調用:then返回的是一個Promise對象,所以能進行鏈式調用。
async/await其實是Promise的語法糖, async 會將其后的函數(函數表達式或 Lambda)的返回值封裝成一個 Promise 對象,而 await 會等待這個 Promise 完成,并將其 resolve 的結果返回出來。
減少前端資源數量,減小前端資源大小,減少dom操作 代碼層面:注意事件的銷毀、路由懶加載、提取公共代碼、css放前面、組件懶加載、減少代碼體積大小、字體圖標代替圖片、使用事件委托、使用查找表、不覆蓋原生方法、減低css選擇器復雜度、使用flex、使用 transform 和 opacity實現動畫
交互優化:減少請求數量、使用 HTTP2(頭部壓縮、鏈路復用、解析快、可設置優先級、流量控制、服務器推送)、減少重繪重排(innerHTML代替DOM操作、避免使用動態屬性、脫離文檔流操作再合并)
加載優化:按需引入、使用CDN、使用服務端渲染、善用緩存、避免卡頓
打包優化:使用gzip、Webpack 對圖片進行壓縮、webpack 按需加載代碼、提取第三庫代碼、webpack物理打包以及配置項打包優化
其他優化:圖片優化(壓縮、懶加載、用webp格式,延遲加載、響應式圖片)、使用工作線程Web Workers、少用全局變量
ES6新增特性常用的主要有:let/const,箭頭函數,模板字符串,解構賦值,模塊的導入(import)和導出(export default/export),Promise,還有一些數組字符串的新方法,其實有很多,我平時常用的就這些。
call,apply,bind主要作用都是改變this指向的,但使用上略有區別,說一下區別:
call和apply的主要區別是在傳遞參數上不同,call后面傳遞的參數是以逗號的形式分開的,apply傳遞的參數是數組形式、Apply是以A開頭的,所以應該是跟Array(數組)形式的參數]
bind返回的是一個函數形式,如果要執行,則后面要再加一個小括號 例如:bind(obj,參數1,參數2,)(),bind只能以逗號分隔形式,不能是數組形式
var:存在變量提升,后面聲明的變量會覆蓋前面的變量聲明、作用域不可控。
let:只能聲明一次,可以重復賦值,形成暫時性死區
cosnt:只能聲明一次,不能重復賦值,形成暫時性死區
Vue是單項數據流,數據雙向綁定
單向數據流主要是vue 組件間傳遞數據是單向的,即數據總是由父組件傳遞給子組件,子組件在其內部維護自己的數據,但它無權修改父組件傳遞給它的數據,當開發者嘗試這樣做的時候,vue 將會報錯。
單頁應用SPA是一種網絡應用程序或網站的模型,它通過動態重寫當前頁面來與用戶交互,這種方法避免了頁面之間切換打斷用戶體驗在單頁應用中,所有必要的代碼(HTML、JavaScript和CSS)都通過單個頁面的加載而檢索
多頁應用MPA(MultiPage-page application),翻譯過來就是多頁應用在MPA中,每個頁面都是一個主頁面,都是獨立的當我們在訪問另一個頁面的時候,都需要重新加載html、css、js文件
我們熟知的JS框架如react,vue,angular,ember都屬于SPA
單頁應用與多頁應用的區別
單頁面應用(SPA) | 多頁面應用(MPA) | |
組成 | 一個主頁面和多個頁面片段 | 多個主頁面 |
刷新方式 | 局部刷新 | 整頁刷新 |
url模式 | 哈希模式 | 歷史模式 |
SEO搜索引擎優化 | 難實現,可使用SSR方式改善 | 容易實現 |
數據傳遞 | 容易 | 通過url、cookie、localStorage等傳遞 |
頁面切換 | 速度快,用戶體驗良好 | 切換加載資源,速度慢,用戶體驗差 |
維護成本 | 相對容易 | 相對復雜 |
單頁應用優缺點
優點:
具有桌面應用的即時性、網站的可移植性和可訪問性
用戶體驗好、快,內容的改變不需要重新加載整個頁面
良好的前后端分離,分工更明確
缺點:
不利于搜索引擎的抓取
首次渲染速度相對較慢
MVVM 由 Model,View,ViewModel 三部分構成,Model 層代表數據模型,也可以在Model中定義數據修改和操作的業務邏輯;View 代表UI 組件,它負責將數據模型轉化成UI 展現出來,ViewModel 是一個同步View 和 Model的對象。
在MVVM架構下,View 和 Model 之間并沒有直接的聯系,而是通過ViewModel進行交互,Model 和 ViewModel 之間的交互是雙向的, 因此View 數據的變化會同步到Model中,而Model 數據的變化也會立即反應到View 上。
ViewModel 通過雙向數據綁定把 View 層和 Model 層連接了起來,而View 和 Model 之間的同步工作完全是自動的,無需人為干涉,因此開發者只需關注業務邏輯,不需要手動操作DOM, 不需要關注數據狀態的同步問題,復雜的數據狀態維護完全由 MVVM 來統一管理。
作用域問題,為了保證互不干擾,因為一個組件是可以共享的,但他們的data是私有的,所以每個組件都要return一個新的data對象,返回一個唯一的對象,不要和其他組件共用一個對象。而且data也是一個閉包的經典使用常見。
this指向直接調用者,而非間接調用者
普通函數中的this:
在Vue所有的生命周期鉤子方法(如created,mounted, updated以及destroyed)里 使用this,this指向調用它的Vue實例,即(new Vue)。
箭頭函數中的this:
箭頭函數沒有自己的this, 它的this是繼承而來; 默認指向在定義它時所處的對象(宿主對象),而不是執行時的對象, 定義它的時候,可能環境是window; 箭頭函數可以方便地讓我們在 setTimeout ,setInterval中方便的使用this
vue生命周期即為一個組件從出生到死亡的一個完整周期,主要包括以下4個階段:創建,掛載,更新,銷毀
創建前:beforeCreate, 創建后:created(有data,無$el)
掛載前:beforeMount, 掛載后:mounted(有data,有$el)
更新前:beforeUpdate, 更新后:updated
銷毀前:beforeDestroy, 銷毀后:destroyed
新增了使用內置組件 keep-alive 來緩存實例,而不是頻繁創建和銷毀(開銷大)
actived 實例激活(該鉤子在服務器端渲染期間不被調用。)
deactived 實例失效 (該鉤子在服務器端渲染期間不被調用。
前端路由實現原理主要通過以下兩種技術實現的
第一種:利用H5的history API實現
主要通過history.pushState 和 history.replaceState來實現,不同之處在于,pushState會增加一條新的歷史記錄,而replaceState則會替換當前的歷史記錄[發布項目時,需要配置下apache]
第二種:利用url的hash實現
我們經常在 url 中看到 #,這個 # 有兩種情況,一個是我們所謂的錨點,路由里的 # 不叫錨點,我們稱之為 hash,我們說的就是hash,主要利用監聽哈希值的變化來觸發事件 —— hashchange 事件來做頁面局部更新
第三種:abstract模式
適用于所有JavaScript環境,例如服務器端使用Node.js。如果沒有瀏覽器API,路由器將自動被強制進入此模式。
總結:hash 方案兼容性好,而H5的history主要針對高級瀏覽器。
路由守衛:
第一種:全局路由鉤子
beforeEach(to,from,next) { }
第二種:路由獨享的鉤子
beforeEnter(to,from,next) {}
第三種:組件內的鉤子
beforeRouteEnter(to,from,next) {}
beforeRouteUpdate(to,from,next) {}
beforeRouteLeave(to,from,next) {}
適用場景:動態設置頁面標題,判斷用戶登錄權限等
vue路由懶加載
vue路由懶加載主要解決打包后文件過大的問題,事件觸發才加載對應組件中的js
replace和push的區別
this.$router.replace方法,不計入history記錄,this.$router.push計入歷史
利用ES5中的Object.defineProperty結合觀察者模式實現的,然后利用里面的getter和setter來實現雙向數據綁定的、發布訂閱模式,數據劫持
首先要對數據進行劫持監聽,設置一個監聽器Observer,用來監聽所有屬性。如果屬性發上變化了,就需要告訴訂閱者Watcher看是否需要更新。因為訂閱者是有很多個,所以我們需要有一個消息訂閱器Dep來專門收集這些訂閱者,然后在監聽器Observer和訂閱者Watcher之間進行統一管理的。接著,我們還需要有一個指令解析器Compile,對每個節點元素進行掃描和解析,將相關指令(如v-model,v-on)對應初始化成一個訂閱者Watcher,并替換模板數據或者綁定相應的函數,此時當訂閱者Watcher接收到相應屬性的變化,就會執行對應的更新函數,從而更新視圖。
異步更新隊列:Vue在觀察到數據變化時并不是直接更新DOM,而是開啟一個隊列,并緩沖在同一個事件循環中發生的所以數據改變。在緩沖時會去除重復數據,從而避免不必要的計算和DOM操作。然后,在下一個事件循環tick中,Vue刷新隊列并執行實際(已去重的)工作。
因為Vue的異步更新隊列,$nextTick是用來知道什么時候DOM更新完成的
vue中的nextTick主要用于處理數據動態變化后,DOM還未及時更新的問題,用nextTick就可以獲取數據更新后最新DOM的變化
適用場景:
第一種:有時需要根據數據動態的為頁面某些dom元素添加事件,這就要求在dom元素渲染完畢時去設置,但是created與mounted函數執行時一般dom并沒有渲染完畢,所以就會出現獲取不到,添加不了事件的問題,這回就要用到nextTick處理
第二種:在使用某個第三方插件時 ,希望在vue生成的某些dom動態發生變化時重新應用該插件,也會用到該方法,這時候就需要在 $nextTick 的回調函數中執行重新應用插件的方法,例如:應用滾動插件better-scroll時
第三種:數據改變后獲取焦點
vue最大特點我感覺就是“組件化“和”數據驅動“
組件化就是可以將頁面和頁面中可復用的元素都看做成組件,寫頁面的過程,就是寫組件,然后頁面是由這些組件“拼接“起來的組件樹
數據驅動就是讓我們只關注數據層,只要數據變化,頁面(即視圖層)會自動更新,至于如何操作dom,完全交由vue去完成,咱們只關注數據,數據變了,頁面自動同步變化了,很方便
jquery主要是玩dom操作的“神器“,強大的選擇器,封裝了好多好用的dom操作方法和如何獲取ajax方法 例如:$.ajax()非常好用
vue:主要用于數據驅動和組件化,很少操作dom,當然vue可能通過ref來選擇一個dom或組件
vue與react:
相同點:數據驅動視圖、組件化、都使用 Virtual DOM
不同點:核心思想不同、組件寫法差異、diff算法不同、響應式原理不同
特性:引入Tree-shaking,多出setup生命周期、響應式API、響應式偵聽、Composition API(組合API)、Fragment、Teleport、Suspense等
v-on 指令常用修飾符:
.stop - 調用 event.stopPropagation(),禁止事件冒泡。
.prevent - 調用 event.preventDefault(),阻止事件默認行為。
.capture - 添加事件偵聽器時使用 capture 模式。
.self - 只當事件是從偵聽器綁定的元素本身觸發時才觸發回調。
.{keyCode | keyAlias} - 只當事件是從特定鍵觸發時才觸發回調。
.native - 監聽組件根元素的原生事件。
.once - 只觸發一次回調。
.left - (2.2.0) 只當點擊鼠標左鍵時觸發。
.right - (2.2.0) 只當點擊鼠標右鍵時觸發。
.middle - (2.2.0) 只當點擊鼠標中鍵時觸發。
.passive - (2.3.0) 以 { passive: true } 模式添加偵聽器
v-bind 指令常用修飾符:
.prop - 被用于綁定 DOM 屬性 (property)。(差別在哪里?)
.camel - (2.1.0+) 將 kebab-case 特性名轉換為 camelCase. (從 2.1.0 開始支持)
.sync (2.3.0+) 語法糖,會擴展成一個更新父組件綁定值的 v-on 偵聽器。
v-model 指令常用修飾符:
.lazy - 取代 input 監聽 change 事件
.number - 輸入字符串轉為數字
.trim - 輸入首尾空格過濾
v-if和v-show都可以顯示和隱藏一個元素,但有本質區別
v-if:是惰性的,只是值為false就不會加載對應元素,為true才動態加載對應元素
v-show:是無論為true和為false都會加載對應html代碼,但為false時用display:none隱藏不在頁面顯示,但為true時頁面上用display:block顯示其效果
適用場景:切換頻繁的場合用v-show,切換不頻繁的場合用v-if
v-for的優先級比v-if更高,這意味著 v-if將分別重復運行于每個 v-for循環中。當你想為僅有的一些項渲染節點時,這種優先級的機制會十分有用,vue3.x則v-if優先級更高
提前使用js的方式表示出dom結構樹來.存儲在內存里面.同樣的循環.只會最終合并執行一次,大大的提高了性能。
(這個地方有點兒像js中的createElementFragment文檔碎片)
而在對比的過程中.通過diff算法進行比較差異.這個比較在我理解而言就是同層比較.降低了時間復雜度空間復雜度一些什么玩意兒.最終把差異同步到真實dom上去.這就是我理解的虛擬dom
在傳統的jq中,操作的都是真實的DOM,.而一個真實dom的渲染過程,要經過渲染引擎構建DOM樹.構建樣式表.組建成render(渲染)樹,的過程,要經過不斷的重繪回流才能夠展示給用戶.
那么在直接js操作dom的過程中,比方說一個循環10次插入dom元素,其實每一次都會經歷上面的過程..經歷大量的重繪回流.代價特別大.性能低下.所以出現了虛擬dom
diff 算法是一種通過同層的樹節點進行比較的高效算法
其有兩個特點:
比較只會在同層級進行, 不會跨層級比較
在diff比較的過程中,循環從兩邊向中間比較
diff 算法在很多場景下都有應用,在 vue 中,作用于虛擬 dom 渲染成真實 dom 的新舊 VNode 節點比較
原理:當數據發生改變時,set方法會調用Dep.notify通知所有訂閱者Watcher,訂閱者就會調用patch給真實的DOM打補丁,更新相應的視圖
第一種:父傳子:主要通過props來實現的
具體實現:父組件通過import引入子組件,并注冊,在子組件標簽上添加要傳遞的屬性,子組件通過props接收,接收有兩種形式一是通過數組形式[‘要接收的屬性’ ],二是通過對象形式{ }來接收,對象形式可以設置要傳遞的數據類型和默認值,而數組只是簡單的接收
第二種:子傳父:主要通過$emit來實現
具體實現:子組件通過通過綁定事件觸發函數,在其中設置this.$emit(‘要派發的自定義事件’,要傳遞的值),$emit中有兩個參數一是要派發的自定義事件,第二個參數是要傳遞的值
然后父組件中,在這個子組件身上@派發的自定義事件,綁定事件觸發的methods中的方法接受的默認值,就是傳遞過來的參數
第三種:兄弟之間傳值有兩種方法:
方法一:通過event bus實現
具體實現:創建一個空的vue并暴露出去,這個作為公共的bus,即當作兩個組件的橋梁,在兩個兄弟組件中分別引入剛才創建的bus,在組件A中通過bus.$emit(’自定義事件名’,要發送的值)發送數據,在組件B中通過bus.$on(‘自定義事件名‘,function(v) { //v即為要接收的值 })接收數據
方法二:通過vuex實現
具體實現:vuex是一個狀態管理工具,主要解決大中型復雜項目的數據共享問題,主要包括state,actions,mutations,getters和modules 5個要素,主要流程:組件通過dispatch到 actions,actions是異步操作,再actions中通過commit到mutations,mutations再通過邏輯操作改變state,從而同步到組件,更新其數據狀態
方法三:使用全局的變量傳遞
在windons或document上聲明或綁定數據,取值
computed是多對一的關系,而watch則是一對多的關系;
methods中都是封裝好的函數,無論是否有變化只要觸發就會執行
computed:是vue獨有的特性計算屬性,可以對data中的依賴項再重新計算,得到一個新值,應用到視圖中,和methods本質區別是computed是可緩存的,也就是說computed中的依賴項沒有變化,則computed中的值就不會重新計算,而methods中的函數是沒有緩存的。Watch是監聽data和計算屬性中的新舊變化。
css沒有局部樣式的概念,vue腳手架通過實現了,即在style標簽上添加scoped
scoped的實現原理:vue通過postcss給每個dom元素添加一個以data-開頭的隨機自定義屬性、然后css根據屬性選擇器添加樣式
第三方庫的樣式穿透:
成對出現:provide和inject是成對出現的
作用:用于父組件向子孫組件傳遞數據
使用方法:provide在父組件中返回要傳給下級的數據,inject在需要使用這個數據的子輩組件或者孫輩等下級組件中注入數據。
使用場景:由于vue有$parent屬性可以讓子組件訪問父組件。但孫組件想要訪問祖先組件就比較困難。通過provide/inject可以輕松實現跨級訪問父組件的數據
provider/inject:簡單的來說就是在父組件中通過provider來提供變量,然后在子組件中通過inject來注入變量
需要注意的是這里不論子組件有多深,只要調用了inject那么就可以注入provider中的數據。而不是局限于只能從當前父組件的prop屬性來獲取數據。
會不定期分享前端知識,歡迎關注,評論,點贊~
原文鏈接:https://juejin.cn/post/7291291652139499535
TML(超文本標記語言)是一種用于創建網頁的標準標記語言,由瀏覽器解析執行。
接下來我來介紹一下簡單的模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
Ps:針對上面的這些HTML,對于初學者而言是不是一頭霧水。
那么接下來,我將為大家一一講述,讓大家明白其中這些標簽的用處。
html元素: 是一個html頁面最外層的標簽(HTML頁面的根元素),其他所有標簽都被它包裹。
head元素: 是一個用來放置頁面信息的標簽(文檔的元數據),如<meta>定義編碼格式,<title>頁面標題等。
body元素: 是一個用來放頁面看得到的內容(可見的頁面內容),如圖表,表格,文字等
html結構介紹
另外簡單貼下兩個標簽,放到body,就可以用瀏覽器看到效果,源碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>小成講前端</h1>
<p>本系列將隔天不定時更新</p>
</body>
</html>
分別是:
h1元素:定義一個大標題
p元素:定義一個段落
(本期完)
小成講前端---本系列將隔天不定時更新
歡迎點贊,關注我!!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。