Vite & Webpack

</tr>
index項目ViteWebpack
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優化

長列表效能優化

  1. 不做響應式:
    比如會員列表、商品列表之類的,只是純粹的資料展示,不會有任何動態改變的場景下,就不需要對資料做響應化處理,可以大大提升渲染速度。
    Vue3 裡則是新增了響應式flag
  2. 虛擬捲動:vue-virtual-scroller、vue-virtual-scroll-list

v-for 遍歷避免同時使用 v-if

列表使用唯一 key

使用 v-show 複用 DOM

無狀態的元件用函數式元件

子元件分割

變數在地化:把會多次參照的變數儲存起來

第三方外掛按需引入

路由懶載入

keep-alive快取頁面

比如在表單輸入頁面進入下一步後,再返回上一步到表單頁時要保留表單輸入的內容、比如在列表頁>詳情頁>列表頁,這樣來回跳轉的場景等

我們都可以通過內建元件 來把元件快取起來,在元件切換的時候不進行解除安裝,這樣當再次返回的時候,就能從快取中快速渲染,而不是重新渲染,以節省效能

  • 也可以用 include/exclude 來 快取/不快取 指定元件
  • 可通過兩個生命週期 activated/deactivated 來獲取當前元件狀態

事件的銷燬

Vue 元件銷燬時,會自動解綁它的全部指令及事件監聽器,但是僅限於元件本身的事件。
而對於定時器、addEventListener 註冊的監聽器等,就需要在元件銷燬的生命週期勾點中手動銷燬或解綁,以避免記憶體洩露。

圖片懶載入:

推薦一個第三方外掛 vue-lazyload
v-LazyLoad 代替 src

SSR優化

Vue2、Vue3區別

index項目Vue2Vue3
1生命週期函數beforeCreate與createdstepup代替beforeCreate與created
2響應式原理apiEs5 Object.defineProperty()進⾏數據劫持,結合發布訂閱的⽅式實現使⽤的是Es6 Proxy代理,使⽤ref或者reactive將數據轉化為響應式數據
3渲染策略提供類似於HTML的模板語法,將模板編譯成渲染函數來返回虛擬DOM樹
1.在DOM樹級別。
2.編譯器積極地檢測模板中的靜態節點、子樹甚至數據對象,並在生成的代碼中將它們提升到渲染函數之外
3.在元素級別。編譯器還根據需要執行的更新類型,為每個具有動態綁定的元素生成一個優化標誌。例如,具有動態類綁定和許多靜態屬性的元素將收到一個標誌,提示只需要進行類檢查。運行時將獲取這些提示並採用專用的快速路徑。
4Diff算法的提升小於Vue3大於Vue2
5打包體積變化未使用的代碼文件都被打包了進去,所以後期項目大了,打包文件會特別多還很大允許現代模式下的module bundler能夠靜態地分析模塊依賴關係,並刪除與未使用的module.exports屬性相關的代碼。模板編譯器還生成了對樹抖動友好的代碼,只有在模板中實際使用某個特性時,該代碼才導入該特性的幫助程序
6建立數據 data選項類型API(Options API)組合類型API(Composition API)
7typeScript的支持支持類型的,用的是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

下劃線表示為 _

中劃線表示為 -

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 取出最大值