index | 項目 | Vite | Webpack |
1 | 原理 | 直接啟動開發伺服器後的打包,請求哪個模組才編譯 | 先打包,然後啟動開發伺服器,請求伺服器給予打包 |
2 | HMR(熱更新) | 改動模組 ,僅需讓柳覽器重新請求該模組 | 相關依賴全部編譯 |
3 | 優點 |
啟動快,做出來的網站google網站評分較高
按需動態編譯的方式,極大的縮減了編譯時間,專案越複雜、模組越多,Vite 的優勢越明顯。
內置支持 TypeScript / less / sass / stylus / postcss(需要單獨安裝所對應的編譯器)
|
生態龐大,遇到問題90% 網路上都有辦法解決。
支持vue-class-component
|
4 | 缺點 |
沒有webpack成熟,無法做到太細部的調整。
生態沒有webpack龐大,遇到問題90%需要自己解決(但現在有越來越好)
vite不支持vue-class-component
|
構建耗時、專案越大編譯速度越慢。
做出來的網站google網站評分較低
|
5 | 環境變數方面 |
Vite預設沒有process.env,必須另外設定。
它有專門的屬性import.meta
除了我們自行定義的環境變數,Vite 還有內建四個它設定的環境變數讓我們運用:
|
Vue優化
長列表效能優化
- 不做響應式:比如會員列表、商品列表之類的,只是純粹的資料展示,不會有任何動態改變的場景下,就不需要對資料做響應化處理,可以大大提升渲染速度。Vue3 裡則是新增了響應式flag
- 虛擬捲動:vue-virtual-scroller、vue-virtual-scroll-list
v-for 遍歷避免同時使用 v-if
列表使用唯一 key
使用 v-show 複用 DOM
無狀態的元件用函數式元件
子元件分割
變數在地化:把會多次參照的變數儲存起來
第三方外掛按需引入
路由懶載入
keep-alive快取頁面
比如在表單輸入頁面進入下一步後,再返回上一步到表單頁時要保留表單輸入的內容、比如在列表頁>詳情頁>列表頁,這樣來回跳轉的場景等
我們都可以通過內建元件
- 也可以用 include/exclude 來 快取/不快取 指定元件
- 可通過兩個生命週期 activated/deactivated 來獲取當前元件狀態
事件的銷燬
圖片懶載入:
推薦一個第三方外掛 vue-lazyload
v-LazyLoad 代替 src
SSR優化
Vue2、Vue3區別
index | 項目 | Vue2 | Vue3 |
1 | 生命週期函數 | beforeCreate與created | stepup代替beforeCreate與created |
2 | 響應式原理api | Es5 Object.defineProperty()進⾏數據劫持,結合發布訂閱的⽅式實現 | 使⽤的是Es6 Proxy代理,使⽤ref或者reactive將數據轉化為響應式數據 |
3 | 渲染策略 | 提供類似於HTML的模板語法,將模板編譯成渲染函數來返回虛擬DOM樹 |
1.在DOM樹級別。
2.編譯器積極地檢測模板中的靜態節點、子樹甚至數據對象,並在生成的代碼中將它們提升到渲染函數之外
3.在元素級別。編譯器還根據需要執行的更新類型,為每個具有動態綁定的元素生成一個優化標誌。例如,具有動態類綁定和許多靜態屬性的元素將收到一個標誌,提示只需要進行類檢查。運行時將獲取這些提示並採用專用的快速路徑。
|
4 | Diff算法的提升 | 小於Vue3 | 大於Vue2 |
5 | 打包體積變化 | 未使用的代碼文件都被打包了進去,所以後期項目大了,打包文件會特別多還很大 | 允許現代模式下的module bundler能夠靜態地分析模塊依賴關係,並刪除與未使用的module.exports屬性相關的代碼。模板編譯器還生成了對樹抖動友好的代碼,只有在模板中實際使用某個特性時,該代碼才導入該特性的幫助程序 |
6 | 建立數據 data | 選項類型API(Options API) | 組合類型API(Composition API) |
7 | typeScript的支持 | 支持類型的,用的是Facebook的Flow做類型檢查 | 借鑒了react hook實現了更自由的編程方式,提出了Composition API,Composition API不需要通過指定一長串選項來定義組件,而是允許用戶像編寫函數一樣自由地表達、組合和重用有狀態的組件邏輯,同時提供出色的TypeScript支持。 |
8 | 事件偵聽器緩存 | 綁定事件每次觸發都要重新生成全新的function去更新 | 提供了事件緩存對象,cacheHandlers,當 cacheHandlers 開啟,會自動生成一個內聯函數,同時生成一個靜態節點。當事件再次觸發時,只需從緩存中調用即可,無需再次更新 |
9 | 異步組件 | - | defineAsyncComponent:
loader:同工廠函數;
loadingComponent:加載異步組件時展示的組件;
errorComponent:加載組件失敗時展示的組件;
delay:顯示loadingComponent之前的延遲時間,單位毫秒,默認200毫秒;
timeout:如果提供了timeout,並且加載組件的時間超過了設定值,將顯示錯誤組件,默認值為Infinity(單位毫秒);
suspensible:異步組件可以退出
onError:一個函數,該函數包含4個參數,分別是error、retry、fail和attempts,這4個參數分別是錯誤對象、重新加載的函數、加載程序結束的函數、已經重試的次數。
|
10 | 自定義渲染render |
h 從 Vue 2.x 的參數傳遞,改為全域導入
渲染函數參數的更動,使狀態元件和函數式元件之間更加一致。
vnode 現在有一個扁平的 prop 結構。
|
h 現在是全域導入,而不是作為參數自動傳遞,render 函式不再接收任何參數。。
|
JavaScript 中的 Var、Let 和 Const 有什麼區別
作用域 | 不同 | 問題 | |
var | 聲明的作用域是全局的或函數/局部的 |
可以重新聲明和修改
聲明的變量會被提升到其作用域的頂部,並使用 undefined 值對其進行初始化
|
|
let | 塊級作用域 |
可以被修改但是不能被重新聲明
聲明的變量會被提升到其作用域的頂部,不會對值進行初始化。
|
|
const | 聲明的變量保持常量值,在塊級作用域內 |
不能被修改並且不能被重新聲明
聲明的變量會被提升到其作用域的頂部,不會對值進行初始化。
|
正則表達式

i 修飾符是用來執行不區分大小寫的匹配。
g 修饰符是用于执行全文的搜索(而不是在找到第一个就停止查找,而是找到所有的匹配)。
[a-z] //匹配所有的小寫字母
[A-Z] //匹配所有的大寫字母
[a-zA-Z] //匹配所有的字母
[0-9] //匹配所有的數字
[0-9\.\-] //匹配所有的數字,句號和減號
[ \f\r\t\n] //匹配所有的白字符
[^a-z] //除了小寫字母以外的所有字符
[^\\\/\^] //除了(\)(/)(^)之外的所有字符
[^\"\'] //除了雙引號(")和單引號(')之外的所有字符
^[a-zA-Z_]$ //所有的字母和下劃線
^a$ // 字母a
^a{4}$ // aaaa
^a{2,4}$ // aa,aaa或aaaa
^a{1,3}$ //a,aa或aaa
^[1-9][0-9]{0,}$ // 所有的正整數
^\-{0,1}[0-9]{1,}$ // 所有的整數
^[-]?[0-9]+\.?[0-9]+$ // 所有的浮點數
^[a-zA-Z0-9_]+$ // 所有包含一个以上的字母、數字或下劃線的字符串
^[1-9][0-9]*$ // 所有的正整數
^\-?[0-9]+$ // 所有的整數
^[-]?[0-9]+(\.[0-9]+)?$ // 所有的浮點數
26 個大小寫英文字母表示為 a-zA-Z
數字表示為 0-9
下劃線表示為 _
中劃線表示為 -
indexOf():檢查某元素是否在陣列中
const myHeroes = ['蝙蝠俠','蜘蛛人','水行俠','黑寡婦']; console.log(myHeroes.indexOf('蟻人')); "沒有找到為-1" -1 console.log(myHeroes.indexOf('水行俠')); // //"索引2就是水行俠:" ,2
js 三元運算子
const age =20; const result =( age>=18 ) ? true:false; console.log( result ) // true
Promise.all
Promise.all
function promeseA (){ return new Premise((resole,reject)=>{ setTimeout(()=>{ console.log('A') resole('A') },1000) }) } function promeseB (){ return new Premise((resole,reject)=>{ setTimeout(()=>{ resole('B') },3000) }) } Promise.all().then(resole=>{ console.log('Promise.all',resole); })
最终返回的结果
//“[object Array] (2) [“A”,”B”]
forEach()
forEach():迴圈的陣列
forEach()本身可帶兩個參數:第一個是必須的 callback 函式,第二個參數thisArg 是可選擇性的。這個callback 函式會將 Array 中的每一個元素作為參數,帶進這個 callback 函式裡,每個元素各執行一次。
第一個 callback 函式則可傳入三個參數:
currentValue 目前被處理的陣列元素值
index 目前被處理的陣列元素索引(可選)
array 呼叫forEach()陣列本身(可選)
const newArr = arr.forEach(function (currentValue, index, array){ //... });
使用箭頭函示的縮寫
const fruits = ["apple", "orange", "cherry"]; fruits.forEach((item, i)=> { console.log(i, item) //0 "apple" //1 "orange" //2 "cherry" });
map():處理陣列
map()
透過函式產生一個新陣列
不會改變原陣列
回傳等於原陣列
如不回傳是undefined
語法
const newArr = arr.map(function (value, index, array){ return ... });
回調函式(callback)與三個參數:value,index,arr
const shoppingCart = [ {itemName: "Book",price : 220 }, {itemName: "Bag",price : 350 } ]; // 使用箭頭函示的縮寫 const itemNames = shoppingCart.map(x => x.itemName ); console.log(itemNames ) // 只把 itemNames 提取出來 itemNames; // ["Book", "Bag"] // 把 price 打七九折後提取出來 const discounts = shoppingCart.map(x => x.price * 0.79); discounts; console.log('折扣:discounts',discounts) // [173.8, 276.5] //小於 50標示無折扣 const prices = [42, 57, 89, 23, 78, 12] const newPrices = prices.map( function(elem) { if(elem < 50) return "無折扣"; return elem }); newPrices; console.log(newPrices) //["無折扣",57,89,"無折扣",78,"無折扣"]
價格大於999元,均8折
map() & Math.max 取出最大值